Symfony2, těší mě!

Symfony

V tomto článku bych chtěl představit hlavní výhody a nevýhody PHP frameworku Symfony2. Osobně věřím, že Symfony2 se zanedlouho stane nejpoužívanějším PHP frameworkem na světě pro střední a větší aplikace a weby.

Zend 1 je dnes již velmi zastaralý, Zend 2 je nevyspělý a nevidím u něj jasnou vizi. Framework Yii se stále drží ActiveRecordu a nevyužívá Dependency Injection. U Nette mi zase vadí pomalý vývoj, lokálnost, mizerná dokumentace a nepodpora některých moderních postupů (anotace, AOP, controllery jako services atd.).

Komunitu Symfony2 tvoří tisíce vývojářů. Framework se rychle rozvíjí, má obsáhlou dokumentaci a mnoho rozšiření (bundles). Jeho jednotlivé komponenty v poslední době začaly využívat nové verze známých open-source řešení jako Drupal 8 (článek), phpBB 4 (článek), Joomla (diskuse) a další.

Právě díky rozdělení frameworku na jednotlivé komponenty nemusíte Symfony2 využívat pouze jako celek. Některé firmy jako např. Medio Interactive využívají Nette v kombinaci s Symfony2 komponentami Console a Dependency Injection.

Symfony2 se používá ve všech zemích kolem nás. V Německu, Švýcarsku, velká poptávka po Symfony vývojářích je i v Anglii. Tohle se Nette zatím nepovedlo a dokud David nezačne pravidelně prezentovat v zahraničí, ani se povést nemůže. Pokud tedy budete chtít někdy pracovat mimo Česko, znalost Symfony2 vám pomůže najít uplatnění výrazně rychleji.

Dependency Injection i u controllerů, anotace

Symfony2 využívá Dependency Injection (DI). Služby se definují v YAML souboru místo Neonu v případě Nette. Ostatní je velice podobné (viz dokumentace). Symfony2 standardně nemá autowiring služeb, což lze ale jednoduše vyřešit instalací některého rozšíření (bundle). Např. můj jednodušší KutnyAutowiringBundle (inspirovaný DI v Nette), případně komplexnější JMSDIExtraBundle nebo AutowiringBundle.

Službou (service) mohou být v Symfony volitelně i controllery. Mám rád, když i u controlleru na první pohled vidím všechny jeho závislosti (v konstruktoru). Příliš mnoho závislostí (6+) mě nutí přemýšlet, jak kód controlleru zjednodušit/dekomponovat.

Užitečná je podpora anotací, např. pro definování routování a použité šablony:

/**
 * @Route(service="controller.hello_world_controller")
 */
class HelloWorldController
{
    /**
     * @Route("/hello-world", name="route.hello_world")
     * @Template("AcmeDemoBundle:HelloWorld:helloWorld.html.twig")
     */
    public function helloWorldAction()
    {
        return array(
            'greeting' => 'Hello world'
        );
    }

}

Anotace můžete v Symfony2 používat ve spoustě dalších případů jako validace formulářů nebo kešování. Mimo to si můžete díky rozšíření JMSAopBundle definovat i vlastní anotace, viz dále.

Aspektově orientované programování (AOP)

Pomocí anotací a AOP si lze často velice usnadnit práci a vyčistit kód. Uvedu příklad. Jak řešíte, když některé proměnné do šablony potřebujete sdílet napříč více controllery? Typicky jméno přihlášeného uživatele, stav jeho kreditu atd. Podědíte controllery? Co spíše controller „obalit“ jiným objektem, který do výstupu controlleru přidá požadované sdílené proměnné?

use Templating\Annotation\FillLayout;

class HelloWorldController extends Controller
{
    /**
     * @Route("/hello-world", name="route.hello_world")
     * @Template()
     * @FillLayout(service="layout_filler.front")
     */
    public function helloWorldAction()
    {
        $templateVariables = array(
            'greeting' => 'Hello world'
        );

        return $templateVariables;
    }
}

// Třída, která přidává do výstupu z controlleru "sdílené proměnné"
class FrontLayoutFiller implements ILayoutFiller {

    public function setDefaultVariables(array $templateVariables) {
        $templateVariables['currentUserName'] = 'Jiří Koutný';
        $templateVariables['currentUserCredits'] = 568;

        return $templateVariables;
    }
}

Díky uvedenému kódu budou proměnné currentUserNamecurrentUserCredits k dispozici v šablonách všech controllerů. Aby vše fungovalo, je potřeba:

  • Definovat u třídy import use Templating\Annotation\FillLayout,
  • U požadované metody použít anotaci @FillLayout(service=“[nazev sluzby]„)

Metoda setDefaultVariables() přejímá výstup z metody helloWorldAction() a „sdílené proměnné“ do výstupu přidá.

Pro lepší pochopení si projděte definici pointcutu, interceptoru a samotné anotace, wiring služeb a případně i dokumentaci k rozšíření JMSAopBundle.

Šablony Twig, Console

Symfony2 používá šablonovací systém Twig, který má podobné funkce jako Latte v Nette včetně dědění šablon, automatického escapování atd. Výhodou Twigu je především lepší podpora v IDE, viz dále. Jinak jsou oba systémy srovnatelné.

Zajímavou komponentou Symfony2 je Console. Umožňuje „ovládat“ Symfony2 aplikaci příkazy z příkazové řádky. Zapisují se následujícím způsobem: $ app/console [název příkazu] [argumenty] tedy např. $ app/console cache:warmup. Příklady nejpoužívanějších příkazů:

  • cache:clear – vymaže všechny keše,
  • doctrine:database:create – vytvoří databázi dle definic Doctrine2 entit,
  • doctrine:schema:validate – zkontroluje, jestli DB schéma odpovídá definicím Doctrine2 entit,
  • assetic:dump –watch – vytvoří různé předkešované javascripty, csska, obrázky atd. a v případě změny je automaticky aktualizuje.

Jako uživateli Windows se mi zpočátku „ovládání“ frameworku přes konzoli nelíbilo. Velice rychle jsem mu ale přišel na chuť. Některá vývojová prostředí (např. PHPStorm) umí příkazy konzole našeptávat, takže si příkazy nemusíte pamatovat.

Mimo systémové příkazy frameworku si můžete vytvářet i příkazy vlastní a automatizovat tak často opakované činnosti. Vytvořili jsme si např. příkazy pro:

  • service:add – přidání libovolné třídy do konfigurace DI containeru,
  • service:sort – abecední seřazení služeb v konfiguraci DI containeru (aby se lépe dělaly merge větví v GITu),
  • test:generate generování skeletonu phpUnit testu pro libovolnou třídu,
  • fixtures:apply – aplikování fixtures (vytvoří schéma databáze dle definice Doctrine2 entit, aplikuje fixtures + example data).

Díky příkazu fixtures:apply je jednoduché přepínat mezi různými větvemi GITu (které např. využívají zcela jinou strukturu databáze):

  1. git checkout [nazev větve]
  2. app/console fixtures:apply

Výborná integrace s Doctrine2

Doctrine2 tvoří jednu ze základních komponent Symfony. Ano, můžete používat Symfony bez Doctrine2. Ve spoustě případů si tím ale zkomplikujete život. Zprovoznění Doctrine je otázkou nastavení několika konfiguračních direktiv. Samozřejmostí je zařazení všech Doctrine2 příkazů do příkazové řádky Symfony (viz výše).

Doctrine entity můžete (ale nemusíte) použít v kombinaci se Symfony formuláři. Po odeslání formuláře máte tedy k dispozici rovnou naplněnou určenou entitu, kterou můžete persistovat.

Podpora v IDE a obrovská komunita

Symfony2 velmi dobře podporují populární vývojová prostředí jako NetBeans (info) nebo PHPStorm (pomocí pluginu). Funguje zvýrazňování syntaxe šablonovacího systému Twig, našeptávání standardních anotací Symfony i Doctrine, našeptávání v konfiguračních souborech a mnoho dalšího.

Framework vyvíjí desítky vývojářů v čele s Fabienem Potencierem. Za posledních 9 měsíců vyšly už 2 velké nové verze a v nejbližší době bude vypuštěna verze 2.3 s dlouhodobou podporou (LTS). Do Symfony přispělo do dnešního dne 796 vývojářů a dalších 527 vylepšovalo dokumentaci.

Každá nová funkce je na Symfony blogu dobře propagována a dokumentována. Kvalitní dokumentace je obecně velkou předností Symfony. Co není v dokumentaci, to při nejhorším rychle najdete na Stackoverflow. Kvalitní dokumentace, rychlost rozvoje frameworku, obrovská komunita a globálnost jsou hlavní důvody, proč pracuji v Symfony2 místo Nette.

Mimo základní komponenty Symfony2 existují další stovky rozšíření (bundles). Pokud potřebujete propojení s Facebookem, použijete FOSFacebookBundle, Bootstrap framework jednoduše přidáte pomocí BootstrapBundle, když potřebujete urychlit načítání obrázků na webu, zvolíte např. SpritesBundle. Všechna rozšíření nainstalujete během chvíle pomocí composeru.

Automatický deployment

Symfony je samozřejmě možné deployovat nahráním souborů na server přes (S)FTP. V tomto případě je ale nutné ručně provést několik operací, které mohou deployment dost protáhnout. Pro pokročilejší uživatele nabízí Symfony promakaný deployovací nástroj Capifony, který vychází z automatizačního nástroje Capistrano.

Capifony umožní celý deploy zcela automatizovat včetně dočasné deaktivace aplikace, stažení zdrojů z repozitáře, instalace všech potřebných závislostí přes composer, kompilace javascriptů Google Closure compilerem, zahřátí keše a mnoho dalšího. Samozřejmostí je možnost vrátit se k předchozí verzi, pokud nasazení nové verze selže.

Nic není dokonalé

Z předchozích odstavců by se vám mohlo zdát, že Symfony2 je dokonalé. Není tomu tak. Za 6 měsíců práce se Symfony 2 v týmu 3 – 4 vývojářů jsem narazil na následující problémy:

Debug komponenta v Symfony je mnohem méně praktická než Laděnka z Nette. Především obsahuje mnohem méně informací a je (samozřejmě subjektivně) méně přehledná. Nepodařilo se nám zjistit, jak ukládat/posílat emailem kompletní výjimky vzniklé na produkčním prostředí. Laděnku z Nette lze naštěstí do Symfony relativně jednoduše přidat.

Symfony codding standards využívají mezery místo tabulátorů. Složené závorky se v jednom případě píšou na stejný řádek (if -else), jindy na nový řádek (class, function atd.). Konfigurační direktivy se nepíší v camelCase, ale v podtrzitkove_notaci atd.

Uvedené nevidím jako zásadní problém a osobně bych se klidně přizpůsobil. Někteří programátoři se ale ohledně standardů dokážou hádat do krve :) Nejen proto jsme ve výsledku používali bez problémů trochu upravené konvence včetně tabulátorů pro odsazování.

Zmíním také, že Symfony je v dev prostředí subjektivně dost pomalé. Pomalost je pravděpodobně způsobena využíváním anotací, neustálým kompilováním DI containeru a především díky velmi komplexní práci s assets pomocí Asseticu (obrázky, css, javascripty). Různými úpravami nastavení se tento problém dal částečně vyřešit, ale i přesto je podle mě pomalost na dev prostředí hlavním trnem v oku Symfony2.

V produkčním prostředí je Symfony2 díky kešování rychlé, ale pouze za předpokladu, že hosting používá APC. To může být u sdílených hostingů problém.

S masivním kešováním na produkci je spojeno také složitější hotfixování případných problémů. Není možné např. pouze upravit anotaci v PHP souboru a znovu načíst stránku. Symfony na produkci spoustu PHP knihoven různě upravuje a kešuje pro jejich rychlejší interpretaci. Velmi často je proto nutné krom samotné úpravy kódu ještě vyčistit keše pomocí cache:clear.

Posledním větším trnem v oku Symfony jsou formuláře. Autor formulářové komponenty (Bernhard Schussek) se vyloženě vyžívá v konfiguracích pomocí složitých asociativních polí (příklad). Bez neustálého koukání do dokumentace tak téměř nikdy nevíte, jak konkrétní formulář/formulářový prvek správně nastavit. Mám pocit, že vždy když se Symfony formuláři pracuji, chovají se úplně jinak. Nic nefunguje na první pokus tak, jak čekáte.

Představil jsem vám ty nejzajímavější vlastnosti, kterými si mě Symfony2 získalo. Bohužel už nezbylo místo na představení Asseticu (lepší správa „assets“, tedy obrázků, css, javascriptů atd.), HTTP kešovováníSecurity komponenty a určitě mnoha dalších.

Ale já už přece jeden framework umím!

V článku v žádném případě nechci hanit Nette. Je to na české poměry výborný framework. Jeho cílovkou jsou ale podle mě spíše menší projekty už např. díky tomu, že nepreferuje objektově-relační mapování (ORM – např. Doctrine2). Místo toho využívá vlastní řešení Nette\Database, které se IMHO pro větší projekty s více vrstvami a více programátory nehodí.

Symfony se nebojí pojmenování „enterprise PHP framework“, protože na větší projekty a businessy primárně cílí. Každý projekt se může postupem času stát velkým, tak proč nezvolit Symfony2 hned na začátku? Jakmile se jej trochu naučíte, tak si dovolím prohlásit, že produktivita bude minimálně srovnatelná s Nette.

Zkuste si Symfony2, základ je podobný Nette. Když se vám nezalíbí jako celek, určitě použijte alespoň některé komponenty, stejně jako Filip,  Tomáš nebo kluci z Media.

Pokud chcete o Symfony2 vědět víc, rád udělám školení. Napište mi na koutny@collabim.com. Pokud v Symfony děláte, podělte se o zkušenosti v komentářích. Díky!

Jirka řídí vývoj webového SEO nástroje Collabim. Mimo SEO a programování ho baví webová analytika.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 52

Přehled komentářů

jirkakoutny Školení
Jaroslav Kubíček Ach ty formuláře
jkucharovic Re: Ach ty formuláře
jirkakoutny Re: Ach ty formuláře
jkucharovic Re: Ach ty formuláře
Jaroslav Kubíček Re: Ach ty formuláře
jkucharovic Re: Ach ty formuláře
jirkakoutny Re: Ach ty formuláře
jkucharovic Ad nevýhody
jirkakoutny Re: Ad nevýhody
jkucharovic Re: Ad nevýhody
jirkakoutny Re: Ad nevýhody
patie
David Grudl Koukám, že Nette vede, pojďme mu pomoci s propagací!
jkucharovic Re: Koukám, že Nette vede, pojďme mu pomoci s propagací!
David Grudl Re: Koukám, že Nette vede, pojďme mu pomoci s propagací!
jirkakoutny Re: Koukám, že Nette vede, pojďme mu pomoci s propagací!
David Grudl Re: Koukám, že Nette vede, pojďme mu pomoci s propagací!
Vojtěch Kohout Re: Koukám, že Nette vede, pojďme mu pomoci s propagací!
bene Re: Koukám, že Nette vede, pojďme mu pomoci s propagací!
jkucharovic Re: Koukám, že Nette vede, pojďme mu pomoci s propagací!
David Grudl Re: Koukám, že Nette vede, pojďme mu pomoci s propagací!
honzamarek88 Re: Koukám, že Nette vede, pojďme mu pomoci s propagací!
maryo Re: Koukám, že Nette vede, pojďme mu pomoci s propagací!
jirkakoutny Re: Koukám, že Nette vede, pojďme mu pomoci s propagací!
maryo Re: Koukám, že Nette vede, pojďme mu pomoci s propagací!
vencza Parádní článek
jirkakoutny Re: Parádní článek
Martin Hlaváč Re: Parádní článek
Martin Hassman Re: Parádní článek
wandal Sila Symfony vs zdroje studia
jirkakoutny Re: Sila Symfony vs zdroje studia
wandal Re: Sila Symfony vs zdroje studia
radek.zilka.3 Re: Sila Symfony vs zdroje studia
martin.bazik symfony sa nechyta
jirkakoutny Re: symfony sa nechyta
martin.bazik Re: symfony sa nechyta
Martin Hasoň Re: symfony sa nechyta
martin.bazik Re: symfony sa nechyta
Jan Machala Re: symfony sa nechyta
jkucharovic Re: symfony sa nechyta
jkucharovic Re: symfony sa nechyta
David Grudl Re: symfony sa nechyta
Martin Hasoň Re: symfony sa nechyta
jkucharovic Re: symfony sa nechyta
martin.bazik Re: symfony sa nechyta
jkucharovic Re: symfony sa nechyta
martin.bazik Re: symfony sa nechyta
martin.bazik Re: symfony sa nechyta
David Grudl Re: symfony sa nechyta
bene
bene Re:
Zdroj: https://www.zdrojak.cz/?p=9097