Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: Damian Rusinek, Piotr Wierzgała, dodany: 18.07.2010 21:50, tagi: symfony

After integrating Symfony with Flex through Zend_Amf, I had to debug it and I needed some logs on server side. Below I present my LoggedAmfServer extending Zend_Amf_Server, which logs all methods called by Flex and its’ responses. You need to pass instance of sfLogger (ie. sfFileLogger) in the constructor.

logger = $l; parent::__construct(); } protected function _handle(Zend_Amf_Request $request) { $responseBody = $request->getAmfBodies(); $body = current($responseBody); if ($body !== false) { $data = $body->getData(); if ($data instanceof Zend_Amf_Value_Messaging_RemotingMessage) { $this->logger->log(sprintf("[Amf Request] CLIENT: [%s] OPERATION: [%s]. PARAMETERS: [%s].", $data->clientId, $data->operation, var_export($data->body, true))); } } parent::_handle($request); } public function handle($request = null) { $response = parent::handle($request); $body = current($response->getAmfBodies()); if ($body !== false) { $data = $body->getData();

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: batman, dodany: 18.07.2010 19:30, tagi: php

Kilka dni temu pisałem o starcie projektu PHP for Android. Zaciekawił mnie on na tyle, że postanowiłem dokładniej mu się przyjrzeć, zwłaszcza procesowi tworzenia i wdrażania aplikacji PHP na telefony wyposażone w system operacyjny Android. Teoretycznie sprawa wydawała się prosta – dowolny edytor do edycji plików, emulator do ich testowania oraz lektura dokumentacji. W praktyce okazało się, że nie jest aż tak różowo. Zakładam, że każdy z was posiada edytor, więc ten krok pominę w opisie procesu tworzenia aplikacji.

PIerwszą rzeczą jaką musimy zrobić, aby móc pisać aplikacje w PHP na Androida, jest pobranie emulatora. Można oczywiście testować skrypty w telefonie, jednak jakoś nie mam odwagi instalować testowych wersji na nietestowym telefonie. Emulator pobiera się razem z Android SDK. Na szczęście nie trzeba nic instalować, więc bałaganu w systemie na nie zrobi. Po pobraniu SKD wystarczy je wypakować w dowolnym miejscu i przejść do katalogu tools, znajdjącego się w katalogu głównym. Zanim będziemy mogli uruchomić emulator Androida, musimy stworzyć wirtualną maszynę (AVD – Android Virtual Machine). W tym celu uruchamiamy wiersz poleceń w katalgu tools .W przypadku systemu operacyjnego Windows, wystarczy przytrzymać lewy klawisz Shift, a następnie kliknąć prawym przyciskiem myszy w katalgu. Z menu kontekstowego wybieramy “Otwórz okno polecenia tutaj”. Nastęnie w wierszu poleceń wpisujemy:

android.bat

Po wykonaniu powyższego polecenia, pojawi się okno menadżera AVD.

avd-manager Zanim będziemy mogli stworzyć wirtualną maszynę, musimy pobrać odpowiednią paczkę. Można to zrobić w zakładce Available Packages. Wybieramy interesującą nas platformę i klikamy w przycisk Install Selected. Mój wybór padł na najnowszą wersję Androida – SDK Platform Abdroid 2.2 (jeśli pojawi się błąd podczas pobierania paczki, musicie zaznaczyć w zakładce Settings checkbox “Force https”). Po pobraniu paczki wracamy do pierwszej zakładki. W końcu możemy stworzyć wirtualną maszynę. W tym celu klikamy w przycisk New. W nowym oknie wpisujemy nazwę maszyny wirtualnej, wybieramy wcześniej ściągniętą paczkę oraz podajemy rozmiar wirtualnej karty SD. Pozostałe opcje możemy w chwili obecnej pominąć.

new-avd

Tak utworzoną maszynę wirtualną uruchamiamy poleceniem

emulator.exe –avd batman

W miejscu batman musicie podać nazwę waszej maszyny wirtualnej. Uruchamianie maszyny może zająć kilka chwil (nawet na mocnym sprzęcie), więc uzbrójcie się w cierpliwość. Po uruchomieniu, przywita was następujący widok:

android-emulator

Jeśli macie ochotę pobawić się samym emulatorem, koniecznie zajrzycie do oficjalnej dokumentacji - http://developer.android.com/guide/developing/tools/emulator.html

Środowisko do testowania mamy już prawie zainstalowane. Do instalacji zostały jeszcze dwie aplikacje: ASE oraz PhpForAndroid.apk. Wystarczy, że emulatorze wejdziecie na stronę http://www.phpforandroid.net/, a nastęnie zainstalujecie znajdujące się na stronie wspomniane aplikacje. Instalacja sprowadza się do pobrania paczek instalacyjnych, a następnie ich uruchomienie. W przypadku PhpForAndroid.apk po instalacji musimy uruchomić aplikację, a nastęnie kliknąć w przycisk Install. Dopiero wtedy w telefonie zainstalowany zostanie interpreter PHP. W końcu możemy zacząć pisać aplikacje na Androida w języku PHP.

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Piotr Śliwa, dodany: 17.07.2010 13:31, tagi: symfony, php

Kilka miesięcy temu popełniłem wpis na temat wielostronicowych formularzy, zaprezentowałem tam m. in. mój plugin do symfony, który tą funkcjonalność automatyzuje. Udostępniłem go niedawno w zbiorze pluginów symfony, znajduje się on tutaj. Między czasie został on zrefaktorowany i zostały dodane nowe klasy.

Wprowadzenie

Główną klasą tego pluginu jest psPageableForm, hermetyzuje ona zarządzanie formularzami. Klasa ta ma podobny interfejs co klasa sfForm, jednakże nie rozszerza jej z tego powodu, gdyż zbyt wiele metod musiałoby być unieważnionych. Podstawowymi metodami klasy wielostronicowego formularza to:
  • psPageableForm::addForm(sfForm) - dodanie formularza na koniec listy (formularz zostaje skojarzony z ostatnią stroną)
  • psPageableForm::setForm(sfForm, int) - dodanie formularza na określoną stronę, formularze ze stron wyższych bądź równych stronie podanej jako argument zostają przesunięte o jedną pozycję dalej.
  • psPageableForm::setUseGlobalNamespace(bool) - czy format poszczególnych formularzy składowych ma zostać spłaszczony do jednego wymiaru, czy też format wielostronicowego formularza oraz formularzy składowych mają zostać połączone ze sobą. Domyślna jest ta pierwsza opcja. Należy wywołać przed dodaniem pierwszego formularza składowego!
  • psPageableForm::setNameFormat(string) - ustawia format nazw widgetów wielostronicowego formularza. Należy wywołać przed dodaniem pierwszego formularza składowego!
  • psPageableForm::setCurrentPageNumber(int) - ustawienie obecnej strony formularza
  • psPageableForm::getCurrentPageNumber() - pobranie obecnej strony formularza
  • psPageableForm::bind(array, array) - wypełnienie formularza danymi oraz jego walidacja
  • psPageableForm::isValid() - sprawdzenie czy wszystkie zwalidowane formularze są prawidłowe, nie oznacza że formularz jest w całości poprawny
  • psPageableForm::getCurrentForm() - pobranie obiektu formularza składowego skojarzonego z obecną stroną
  • psPageableForm::setPersistanceStrategy(psPageableFormPersistanceStrategy) - ustawienie strategii trwałości

Istnieje również interfejs strategii trwałości, który deklaruje trzy metody:

  • psPageableFormPersistanceStrategy::persist(psPageableForm) - zapisanie formularza do źródła danych
  • psPageableFormPersistanceStrategy::getValues() - pobranie zapisanych wartości formularza
  • psPageableFormPersistanceStrategy::clear() - wyczyszczenie obiektu
Na dzień dzisiejszy są trzy implementacje tego interfejsu:
  • psPageableFormPostPersistanceStrategy - przechowuje wartości w ukrytych polach formularza
  • psPageableFormSessionPersistanceStrategy - przechowuje wartości w sesji
  • psPageableFormDatabasePersistanceStrategy - przechowuje wartości w bazie danych (wykorzystanie Doctrine)
Ostatnią klasą jest psPageableFormProcess, która automatyzuje przetwarzanie formularza, dba o odpowiednie ustawianie numerów stron podczas niepoprawnej walidacji oraz o odpowiedni stan formularza. Jedyną jej metodą (oprócz konstruktora) to metoda psPageableFormProcess::process(), która to w odpowiedni sposób przetwarza formularz. Dzięki tej klasie kod w kontrolerze jest zredukowany do minimum.

Przykład

Utworzenie wielostronicowego formularza sprowadza się do utworzenia kilku zwykłych formularzy symfony - jeden formularz na jedną stronę. Następnie definiujemy podklasę psPageableForm.

[PHP]
  1. class PageableForm extends psPageableForm
  2. {
  3. public function setup()
  4. {
  5. $this->setNameFormat('form[%s]');
  6. $this->setUseGlobalNamespace(false);
  7.  
  8. //wyłączenie ochrony csrf dla wszystkich formularzy z wyjątkiem ostatniego
  9. $form1 = new Form1(array(), array(), false);
  10. $this->addForm($form1);
  11.  
  12. $form2 = new Form2(array(), array(), false);
  13. $this->addForm($form2);
  14.  
  15. $form3 = new Form3();
  16. $this->addForm($form3);
  17. }
  18. }

W kontrolerze tworzymy obiekt zdefiniowanej klasy, ustawiamy strategię trwałości, tworzymy obiekt klasy psPageableFormProcess z odpowiednimi parametrami oraz wywołujemy metodę psPageableFormProcess::process().

[PHP]
  1. public function executeProcess(sfWebRequest $request)
  2. {
  3. $form = new PageableForm();
  4. $form->setPersistanceStrategy(new psPageableFormSessionPersistanceStrategy($this->getUser()));
  5. $process = new psPageableFormProcess($form, $request, function(){
  6. // funkcja zwrotna wywoływana gdy formularz zostanie w całości poprawnie zwalidowany
  7. }, array('formParameterName' => 'form')
  8. );
  9. $process->process();
  10. $this->form = $form;
  11. }

W szablonie wyświetlamy formularz z obecnej strony.

[PHP]
  1. <form action="<?php echo url_for('module/action?step='.($form->getCurrentPageNumber() + 1)) ?>" method="post">
  2. <?php echo $form->getCurrentForm() ?>
  3.  
  4. <?php if($form->getCurrentPageNumber() > 1): ?>
  5. <a href="?step=<?php echo $form->getCurrentPageNumber() ?>">Wróć</a>
  6. <?php endif; ?>
  7. <input type="submit" value="dalej" />
  8. </form>

Więcej przykładów z kodem źródłowym znajdziecie tutaj.

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Athlan, dodany: 17.07.2010 12:04, tagi: sql

Oblicza MySQL nie są do końca znane przy tworzeniu aplikacji, a problemy optymalizacyjne stają się nie lada problemem przy funkcjonowaniu wersji produkcyjnej projektu. Nie sposób przewidzieć wszystkich możliwości użycia pól, założenia zarówno wspólnych, jak i pojedynczych indeksów posiadających zakładaną przez nas moc i zajętą pamięć na dysku.

Ostatnimi czasy budowałem dość skomplikowany projekt, jeżeli chodzi o złożoność zapytań i wykonywanych przez nie operacje matematyczne. Pomimo tego, że aplikacja była doskonale przemyślana, a struktury bazy danych perfekcyjnie jej podporządkowane, gdzieś tkwił problem, bowiem jedno z zapytań generowało pozornie prosty (wizualnie) rezultat, baza reagowała na zapytanie dopiero po 2.5 sekundy dla 30k+ rekordów. Patrząc na strukturę kluczy i zapytania, zwłaszcza, że pola, na których operowałem były różnego rodzaju liczbami i datami zacząłem się poważnie martwić i rozkładać zapytanie na czynniki pierwsze, kończąc na warunkach. Wyobraźcie sobie moje zdziwienie, gdy doszedłem do tego, że całe obciążenie (ponad 2.3 sekundy) generował warunek:

WHERE DATE(ticket_date) &gt;= " ... "

Gdzie ticket_date to pole typu DATETIME. Od razu doszedłem do wniosku, że w parze idzie złe przygotowanie danych przez PHP, a angażowana jest w to wszystko baza, na której forsuje się użycie funkcji DATE(). Przynajmniej dla 30k+ rekordów zindeksowanego pola. Prosty zabieg zamiany jednej linijki kodu na drugą przyniósł porządane efekty.

$aTerms[] = 'DATE(ticket_date) &gt;= "' . $sDate . '"'
$aTerms[] = 'ticket_date &gt;= "' . date('Y-m-d H:i:s', strtotime($sDate)) . '"'

Budując aplikację zwracam szczególną uwagę na strukturę bazy, indeksowanie pól, rysuję diagramy przewidujące wykorzystanie danych pod różne zapytania, ale… tak banalny błąd przy przeanalizowanej aplikacji rozłożył mnie na łopatki. Z drugiej strony, zapomniałem o jednej bardzo ważnej rzeczy: maksymalnym odciążeniu bazy danych przy preparowaniu argumentów warunków, skoro warunki te mogą być w odpowiedni i przede wszystkim szybki sposób spreparowane na poziomie modelu (abstrakcyjnie rzecz ujmując, pozbywam się pojęcia PHP), który przygotują zapytanie tylko do wykonania operacji na surowych danych, bez konieczności ich ewentualnego przeliczania. Oczywiście nie zawsze taki efekt da się uzyskać, ale należy to maksymalnie optymalizować.

Jedno jest wiadome: przeliczanie DATE() dla rekordów w warunku jest nieoptymalne dla pola DATETIME.

Autor wpisu: batman, dodany: 15.07.2010 20:16, tagi: php

Pisałem wczoraj o projekcie umożliwiającym tworzenie aplikacji PHP działających na Androidzie. Dzisiaj twórcy projektu zaprezentowali nowe logo oraz zaktualizowali roadmap.

Logo jest miksem pehapowego słonia oraz zielonego androida i nazywa się Pfaewok.

W kwestiach technicznych również zaszły pewne zmiany. Zaktualizowana została mapa projektu (roadmap) i obecnie wygląda następująco:

  • lipec – sierpień 2010
    • testy wersji 0.1 i wprowadzanie poprawek do znalezionych błędów
    • uzupełnienie manuala oraz dokumentacji, m. in. opisu dotyczącego instalacji i korzystania z emulatora
  • wrzesień – październik 2010
    • wypuszczenie wersji 0.2
    • udostępnienie repozytorium z kodem źródłowym
    • stworzenie issue trackera
    • kolejne modyfikacje manuala i dokumentacji
  • listopad – ? 2010
    • wydanie kolejnej wersji projektu
    • aktualizowanie projektu wraz z aktualizacjami SL4A
    • aktualizacja manuala i dokumentacji

Autor wpisu: sokzzuka, dodany: 15.07.2010 00:19, tagi: php

Pewnego dnia, jadąc w nocy na rowerze zamyśliłem się na temat klas, funkcji i obiektów. Przemyślenia te zawiodły mnie do pewnych ciekawych wniosków. Nie będę ich tutaj w tej chwili przytaczał, natomiast wpadł mi do głowy pewien ciekawy pomysł jak zrealizować wzorzec singleton w alternatywny sposób, opierając się na funkcjach anonimowych.

Czym jest wzorzec Singleton ? Pokrótce mówiąc, stosujemy go jeżeli a) chcemy mieć tylko jedną instancję obiektu, b) jeżeli chcemy aby nasz obiekt był globalnie dostępny.

Jednym z wzorców, który korzysta z singletona jest rejestr, większość z Was pewnie używała go w Zendzie gdzie jest nagminnie wykorzystywany. Dla przypomnienia:

//inicjalizacja singletona
$oReg = Zend_Registry::getInstance();
//ustawienie zmiennej w rejestrze
$oReg->jakis_klucz = 'jakas wartosc';
//pobranie
echo $oReg->jakis_klucz;

Jedną z rzeczy, którą uważam za złą w tej implementacji od strony filozoficznej jest to, że klasy generalnie definiujemy po to by tworzyć wiele instancji danego obiektu. W tym przypadku potrzebujemy tylko jeden egzemplarz, stosując klasy trzeba używać więc dodatkowych sztuczek. Natomiast zamiast tworzyć klasę i bawić się w Singletona z klasą rejestru stworzyć taką oto zgrabną funkcję:

function Registry($key, $value = null){
    static $reg;
    if($value === null){
        return $reg[$key];
    } else {
        $reg[$key] = $value;
    }
}
//ustawianie
Registry('a','b');
Registry('d','e');
//pobieranie
echo Registry('a');
echo Registry('d');

Jak widać implementacja jest prosta jak budowa czołgu t-52 i realizuje wszystkie założenia rejestru – jedna instancja i globalna dostępność elementów które przechowuje.

Przejdźmy dalej i spróbujmy zaimplementować Singletona w podobny sposób, ale już jako konkretny obiekt z metodami. Klasyczne podejście wygląda mniej więcej tak:

class My_Singleton {
    protected static $_instance = null;
    private $_prywatna1 = 'aaa';
    private $_prywatna2 = 'bbb';
 
    protected __construct(){
 
    }
    public getInstance(){
        if(self::$_instance === null){
            self::$_instance = new self;
       }
       return self::$_instance;
    }
    public function method1(){
        echo $this->_prywatna1.' <br/>';
        $this->_prywatna2 = 'ccc';
    }
    public function method2(){
        echo $this->_prywatna2.' <br/>';
    }
}
 
My_Singleton::getInstance()->method1();
My_Singleton::getInstance()->method2();

Alternatywne podejście:

class Proxy {
    function  __call($name,  $arguments) {
        if(is_callable($this->$name)){
            return call_user_func_array($this->$name, $arguments);
        }
    }
}
 
function Singleton() {
    static $self;
    //konstruktor pol
    if($self == null) {
        $self = new stdClass();
        $self->_prywatna1 = 'aaa';
        $self->_prywatna2 = 'bbb';
    }
    //konstruktor metod
    static $oObj;
    if($oObj == null) {
        $oObj = new Proxy();
        $oObj->method1 = function() use ($self) {
                    echo $self->_prywatna1.' <br/>';
                    $self->_prywatna2 = 'ccc';
                };
        $oObj->method2 = function() use ($self) {
                    echo $self->_prywatna2.' <br/>';
                };
    }
 
    return $oObj;
}
 
Singleton()->method1();
Singleton()->method2();

Technika przedstawiona powyżej jest bardzo podobna do programowania opartego na prototypach, z jakim mamy np do czynienia w JavaScript’cie. Jedyną różnicą w ciele metod „metoda1″ i „metoda2″ jest zastąpienie zmiennej $this, zmienną $self, spowodowane tym, że $this jest zastrzeżoną nazwą zmiennej. Przykład spełnia założenia Singletona – jedna instancja i dostępność w kontekście globalnym. Jedyną wadą tego rozwiązania jest to, że nie da się dziedziczyć po takim obiekcie, mam wrażenie jednak, że nie jest to koniecznie potrzebne.

Ciekawy jestem Waszego zdania o tej technice, zapraszam do komentowania ;)

P.S przykłady działają tylko w PHP 5.3.x

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: batman, dodany: 14.07.2010 18:00, tagi: php

Na blogu PHP Classes pojawił się dziś ciekawy wywiad z Iván Mosquera Paulo, głównym deweloperem PHP for Android. Opowiada on o nowym projekcie, którego celem jest umożliwienie tworzenia aplikacji na telefony wyposażone w system operacyjny Android w języku PHP. Zasada działania jest prosta. Najpierw należy zainstalować ASE (Android Scripting Environment), czyli środowisko, które pozwala na tworzenie i wykonywanie skryptów mających dostęp do API systemu operacyjnego. Następnie należy zainstalować PhpForAndroid.apk, który tak na prawdę nie jest aplikacją, tylko zbiorem niezbędnych komponentów, bez których aplikacje PHP nie będą działać. W skład pakietu wchodzi PHP CLI z zainstalowanymi dwoma modułami – socket oraz JSON. Jak widać nie ma tutaj żadnego serwera, na którym wykonują się skrypty PHP.

Projekt ma dopiero jeden dzień (wystartował 13.07.2010) i jeszcze długa droga przed nim, jednak można już zobaczyć jak wygląda przykładowy kod:

require_once("Android.php");
$droid = new Android();
$droid->vibrate();

Jak widać kod jest banalny i raczej nie wymaga wyjaśnienia. Oczywiście “prawdziwe” aplikacje będą dalece bardziej złożone, jednak już teraz widać jak będą one tworzone. Więcej przykładów można znaleźć w manualu.

Projekt jest zbyt świeży, by można w jakikolwiek sposób ocenić czy ma szansę powodzenia. W znacznej mierze sukces tej technologii będzie zależał od społeczności, która powstanie wokół tego projektu oraz od aplikacji jakie będą powstawać.

źródło: www.phpclasses.org/blog

Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.