Symfony 2: pierwsze wrażenia
Nowości w Symfony 2
- PHP 5.3 jako standard i korzystanie z przestrzeni nazw
- Zupełnie nowy kod, zdecydowane odchudzenie klas, czuć lekkość
- Dependency Injection (IoC)
- Events
- Modułowa architektura, nie tylko pod postacią katalogów o nazwie modules/plugin
- Rezygnacja z pluginów jako mikroaplikacji na rzecz Bundles
- Źródła hostowane na GitHub
Bundle 1: Marketing
Prezentacje, konferencje, świetny design stron przemawiają za rewolucyjnością nowego produktu SensioLabs .
Faktycznie, w świecie PHP może być to jakaś rewolucja, ale chyba głównie za sprawą samego PHP 5.3 i namespaces zaciągniętych z “szóstki”. A źrodła Symfony? Ano jak to PHP - trochę Javy trochę C, np. klasy Request/Response w których zaimplementowano tylko akcesory (powstają obiekty o niezmiennym stanie). W Django najważniejsze middleware opierają się na możliwości modyfikacji obiektu Request dodając np. właściwość user. Proste i dziala. W Symfony 2 to nie przejdzie, ubijany jest dynamizm języka programowania.
Bundle 2: Dependency Injection
Kiedyś bardzo potrzebowałem takiego mechanizmu. Otóż za pomocą konfiguracji (PHP/Yaml/XML/etc) można zdefiniować skonfigurowane usługi pod unikalnymi nazwami. Konfiguracja może odbywać się przez wstrzyknięcie argumentów do konstruktora lub wybranych metod (argumentami mogą być wartości lub odwołania do innych zdefiniowanych usług).
W teorii można swobodnie wymieniać/parametryzować poszczególne instancje klas. W praktyce stosuje się to rzadko lub wcale.
Popełniłem kiedyś taki plugin do Symfony 1.x - sfIocPlugin
- wzorowałem się na IoC ze Springa
. Dependency Injection w Symfony może przydać się przy większych projektach, gdzie pewne usługi mogą być wymienialne w zależności od wdrożenia. Osobiście jednak uważam, że realizacja “większych projektów” w PHP
to utopia. Może komuś się to jednak przyda.
EDIT: Dependency Injection sprawdza się w unit testach (o ile środowisko unit testów umożliwia użycie DI), szczegóknie w połączeniu z mock-objects.
Bundle 3: Events
System zdarzeń w Symfony 2 jest prosty. Jest dość dobrą realizacją wzorca obserwatora. Autor przyznaje, że wzorował się na notyfikacjach z Cococa.
Implementacja ta przypomina mi naszego firmowego EventBrokera napisanego chyba w 2006 roku. Osobiście wolę django.signals z racji rejestrowania obserwatora do konkretnej instancji sygnału. Z kolei w Symfony obserwator (listener) rejestrowany jest w instancji dispatchera podając nazwę sygnału.
Nasuwają się dwie wady (z doświadczenia):
- dispatcher może nie mieć zarejestrowanego zdarzenia (trzeba znaleźć odpowiedni dispatcher, przez który będzie przebiegał event),
- rejestracja i notyfikacje odbywają się przez nazwę - robiąc literówkę przy connect nie mamy szans na informacje o błędzie; takie błędy znajduje się zwykle po kilku godzinach.
Bundle 4: Super wydajność
Wydajność została zwiększona, ale nie uważam że o te mityczne 2.5x.
Benchmark strony “Congratulations…” (index.php
) z sandboxa, dla ab -c 100 -n 1000
:
- Symfony 2: 32.18 [#/sec]
- Symfony 1.2: 19.58 [#/sec]
To jest nieco powyżej 1.5x. Żeby jednak trochę podrasować wersję 1.2 wyłączyłem w settings.yml użycie bazy danych (test Symfony 2 też nie używał BD).
Widok o podobnej złożoności w Django serwowany jest nawet do 200 rq/sec. Strona główna portalu opartym na Django (z użyciem memcache) jest serwowana w trybie developerskim w porywach do 160 req/sec.
Wydajność Symfony 2 nie zachwyca.
Bundle 5: Formularze
Czytałem tylko kod. Są to niemal te same nieudolne formularze, o których już pisałem - Symfony forms vs Django forms
Podsumowanie
Szkoda czasu.