Symfony console utilita
Každý Symfony projekt má vo svojom bin
adresári console
utilitu. Táto utilita plní viacero úloh. Poskytuje nám informácie o projekte, manažuje lokálny webový server, poskytuje linting, alebo generuje šablóny kódu, tzv. scaffolding. (Pre scaffolding potrebujeme mať nainštalovaný Symfony maker.)
$ php bin/console Symfony 4.2.4 (env: dev, debug: true) Usage: command [options] [arguments] Options: -h, --help Display this help message -q, --quiet Do not output any message -V, --version Display this application version --ansi Force ANSI output --no-ansi Disable ANSI output -n, --no-interaction Do not ask any interactive question ...
Všetky možnosti utility console
dostaneme, ak ju spustíme bez volieb: php bin/console
.
Prvá aplikácia
Pomocou composera vytvoríme prvú skeleton aplikáciu.
$ composer create-project symfony/skeleton first
Vygeneruje sa Symfony aplikácia s minimálnymi závislosťami. Projekt sa vytvorí v podadresári first
.
$ cd first
Nezabudnime sa premiestniť do nového adresára. Toto je častá chyba u začiatočníkov. V krátkosti si opíšeme obsah nášho projektového adresára.
$ ls -Ap .env bin/ composer.lock public/ symfony.lock vendor/ .gitignore composer.json config/ src/ var/
V adresári bin
máme už spomínanú console
utilitu. V adresári public
sa umiesťňujú webové súbory, vrátane HTML, CSS a JS súborov. V tomto momente sa tam nachádza len súbor index.php
, ktorý má úlohu front controllera a vykonáva bootstrapping. Front controller je návrhový vzor, ktorého úlohou je prijať a preposlať všetky prichádzajúce požiadavky od klientov. Spring používa pre tento objekt prihliehavý názov dispatcher
. Pod bootstrappingom sa myslí štart systému, v našom prípade Symfony frameworku. Pre nás je však tento súbor nepodstatný a nemusíme sa ním zaoberať.
Závislosti projektu sa nachádzajú v adresári vendor
. Ako nám už názov napovedá, config
adresár obsahuje rôzne konfiguračné súbory projektu. Zdrojový kód sa píše do adresára src
. Adresár var
obsahuje dočasné dáta, ako sú napríklad logy.
V súbore composer.json
máme zaznamenané závislosti composera. V pomocnom súbore composer.lock
máme presné verzie knižníc a ich závislostí. Kvôli prenositeľnosti a minimalizícii konfliktov.
V súbore .gitignore
sa nachádzajú súbory a adresáre, ktoré sa majú vyňať z posielania do repositárov. (Repozitáre sú úložiská kódu, kde si vývojári skladujú svoj vytvorený kód. Symfony pracuje s git systémom.) Patria sem napríklad adresáre vendor
alebo var
.
Podľa najnovších vývojárskych trendov sa citlivé a dôležité konfiguračné údaje uchovávajú v premenných prostredia. Tieto premenné s východzími nastaveniami máme v súbore .env
. Nájdeme tam napríklad databázové prihlasovacie údaje. Súbor .env
uľahčuje nasadzovanie aplikácie na rôzne systémy. Keďže sa komituje do repozitárov, nesmú sa v ňom nachádzať citlivé údaje.
Tu došlo v minulom roku ku zmene, keď Symfony mal súbor .env.dist
, ktorý sa komitoval, a .env
, ktorý bol z repozitárov vyňatý. V najnovších verziách sa upustilo od .env.dist
súboru a .env
sa naopak komituje. Úlohu .env.dist
nahradili .env.local
alebo .env.(dev/test/prod).local
.
Ďalším krokom býva štandardne inicializácia nového git repozitára. Keďže však našou úlohou je spoznávať Symfony, git zatiaľ nebudeme potrebovať.
$ composer info ... symfony/finder v4.2.4 Symfony Finder Component symfony/flex v1.2.0 Composer plugin for Symfony symfony/framework-bundle v4.2.4 Symfony FrameworkBundle symfony/http-foundation v4.2.4 Symfony HttpFoundation Component symfony/http-kernel v4.2.4 Symfony HttpKernel Component symfony/polyfill-mbstring v1.10.0 Symfony polyfill for the Mbstring extension symfony/routing v4.2.4 Symfony Routing Component ...
Pomocou príkazu composer info
si môžeme zistiť, aké závislosti máme v danom momente nainštalované. Keďže sme si vytvorili skeleton aplikáciu, budeme potrebovať nainštalovať celý rad ďalších komponentov. Preto sa bude náš zoznam závislostí pomaly ale isto rozrastať.
$ php bin/console about -------------------- ------------------------------------------- Symfony -------------------- ------------------------------------------- Version 4.2.4 End of maintenance 07/2019 End of life 01/2020 -------------------- ------------------------------------------- Kernel -------------------- ------------------------------------------- Type App\Kernel Environment dev Debug true Charset UTF-8 Cache directory ./var/cache/dev (4.5 MiB) Log directory ./var/log (0 B) -------------------- ------------------------------------------- PHP -------------------- ------------------------------------------- Version 7.2.11 ...
Podrobné informácie o projekte môžeme získať pomocou príkazu php bin/console about
.
Pridávanie základných závislostí
Nainštalujeme si tri základné závislosti. Ako názvy použijeme aliasy balíčkov.
$ composer req dumper profiler server --dev
Niektoré balíčky môžu mať aj viacero aliasov. Napríklad profiler
je alias pre symfony/profiler-pack
. Súhrn aliasov pre balíčky nájdeme na flex.symfony.com
Voľbou --dev
sa tieto balíčky zaradia do development prostredia. V Symfony existujú tri základné prostredia: dev
, test
a prod
. Je možnosť si vytvoriť tiež ďalšie vlastné prostredie. Pod prostredím (Environment) sa chápe báza kódu s určitými konfiguračnými nastaveniami.
Dumper nám poskytuje výborné nástroje na debugovanie: dump()
, resp. dd()
. Pomocou nich môžeme počas vývoja prezerať obsah premenných. Funkcia dd()
je kombináciou dump()
a exit()
.
public function about(Request $request): Response { dump($request); ... }
V našom prípade si prezeráme obsah objektu Request
. Ide o veľmi šikovný a dobre vyladený nástroj, ktorý je neoceniteľný pre vývojára.
Profiler je ladiaci panel, ktorý nám počas vývoja aplikácie poskytuje podrobné informácie o požiadavkách, logoch, alebo zabezpečení.
Server nám dáva k dispozícii vývojársky PHP server. Ten sa spúšťa príkazom php bin/console server:start
. (Pre Windows server:run
). Po spustení servera nájdeme na adrese http://127.0.0.1:8000/
Symfony uvítaciu stránku.
Symfony maker
Symfony maker vytvára čiastočne zhotovené triedy, testy, migrácie, Twig šablóny, rôzne súbory a adresáre. Pomáha nám generovať opakujúci sa kód; v angličtine sa takému kódu hovorí boilerplate. Procesu tvorby častí projektu sa hovorí scaffolding.
$ composer req maker
Príkaz nainštaluje symfony/maker-bundle
. Bundle termín sa používa pre Symfony knižnice, ktoré sú dodatočné ku core systému. Pre knižnice, ktoré tvoria jadro systému sa používa termín component.
$ php bin/console list make ... make:command Creates a new console command class make:controller Creates a new controller class make:crud Creates CRUD for Doctrine entity class make:entity Creates or updates a Doctrine entity class ... make:fixtures Creates a new class to load Doctrine fixtures make:form Creates a new form class ...
Zoznam príkazov pre maker dostaneme pomocou php bin/console list make
.
Chystáme sa vytvoriť prvý controller. Keďže sa pritom používajú anotácie, potrebujeme tiež doinštalovať sensio/framework-extra-bundle
. Balík si stiahneme pomocou jeho aliasu annotations
.
$ composer req annotations
Ide o bundle, ktorý umožňuje konfigurovať controllery pomocou anotácií. Inštalácia týchto rôznych balíčkov môže to vyzerať na prvý pohľad komplikovane. Avšak composer nás vždy upozorní na chýbajúcu závislosť a po čase sa tieto úkony úplne zautomatizujú.
$ php bin/console make:controller HomeController created: src/Controller/HomeController.php created: templates/home/index.html.twig
Pomocou php bin/console make:controller
vytvoríme nový controller s názvom HomeController
. Symfony maker vytvorí pritom dva súbory: HomeController.php
a index.html.twig
.
Controller
Controller je trieda, ktorá spracuje požiadavku od klienta, deleguje úlohy pre biznis logiku, a vráti klientovi výstup vo forme HTML, JSON, alebo PDF. Požiadavka je spracovaná vo funkcii, ktorej sa hovorí akcia (action). Symfony dokumentácia neodporúča používať slovo akcia v názvoch funkcií.
Symfony má vo svojich best practices nasledovné odporúčanie:
Symfony follows the philosophy of „thin controllers and fat models“. This means that controllers should hold just the thin layer of glue-code needed to coordinate the different parts of the application.
Controller sa nemá využívať na vykonávanie biznis logiky. Controller deleguje úlohy iným častiam aplikácie a preposiela výsledky. Ideálne by mali byť akcie čo najštíhlejšie. V našich príkladoch budeme niekedy kvôli jednoduchosti vykonávať biznis logiku aj v controlleri; v produkčnom nasadení sa však treba pridŕžať tohoto odporúčania.
Mapovaniu URL cesty požiadavky (napr. /about
) na funkciu controllera sa hovorí routing. Routing v Symfony je možné nastaviť pomocou anotácií, YAML súboru, XML súboru, alebo pomocou PHP kódu. Táto komplexná flexibilita mi silne pripomína Spring framework. Najčastejšie sa zrejme na routing používajú anotácie.
Textová odpoveď
Obyčajnú textovú odpoveď môžeme vytvoriť s Symfony\Component\HttpFoundation\Response
. HttpFoundation
komponent tvorí objektovú vrstvu nad HTTP špecifikáciou. Ukrýva pre nami detaily ako sú PHP globálne premenné.
<?php // src/Controller/HomeController.php namespace App\Controller; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; class HomeController extends AbstractController { /** * @Route("/home", name="home") */ public function index(): Response { return new Response("Hello there", Response::HTTP_OK, ['content-type' => 'text/plain']); } }
Na URL cestu /home
sme namapovali pomocou @Route
anotácie funkciu index()
. PHP nemá anotácie ako má Java alebo Python, preto bola vytvorená zvlášť knižnica pre parsovanie anotácií v komentároch. Funkcia vracia jednoduchú textovú odpoveď.
class HomeController extends AbstractController
Symfony maker nám vytvoril kostru controllera, ktorý dedí z triedy AbstractController
. Dediť môžeme aj z triedy Controller
, Symfony však odporúča AbstractController
. AbstractController
nám dáva k dispozícii predpripravené funkcie pre renderovanie šablón, forwarding, redirecting, alebo tvorbu JSON odpovede.
$ public function index(): Response
Všimnime si používanie typových hintov. Od PHP verzie 7 môžeme používať typové hinty pre návratové hodnoty funkcií. To nám umožňuje zachytiť veľa chýb pri vývoji.
Potom, čo si naštartujeme development server, môžeme si otestovať poslanie našej prvej požiadavky.
$ curl localhost:8000/home Hello there
Na takého jednoduché testovanie sa hodí utilitka curl
.
JSON odpoveď
Pre odpoveď vo formáte JSON použijeme Symfony\Component\HttpFoundation\JsonResponse
.
/** * @Route("/colours", name="colours") */ public function colours(): JsonResponse { $colours = ['red', 'green', 'blue', 'steelblue']; return new JsonResponse(['colours' => $colours]); }
Nová akcia vracia dáta vo formáte JSON.
$ curl localhost:8000/colours {"colours":["red","green","blue","steelblue"]}
Znova si to otestujeme pomocou curl
.
Twig šablóna
Ďalej si ukážeme ako poslať HTML odpoveď, ktorú vygenerujeme pomocou Twig šablóny.
$ composer req twig
Potrebujeme si najprv nainštalovať Twig. Ten sa nachádza v symfony/twig-bundle
. Šablóny sa v Symfony ukladajú do adresára templates
.
/** * @Route("/names", name="names") */ public function names(): Response { $names = ['Paul', 'Thomas', 'Julia', 'Betty']; return $this->render('home/index.html.twig', ['names' => $names]); }
Tretia akcia vracia HTML výstup. Premenná $names
obsahuje dáta, ktoré sa prepošlú šablóne na spracovanie. HTML výstup sa vygeneruje pomocou funkcie render()
, ktorú sme zdedili z AbstractController
triedy. Ako prvý parameter funkcia prijíma názov šablóny. Druhým parametrom sú dáta.
{# templates/home/index.html.twig #} {% extends 'base.html.twig' %} {% block title %}Home page{% endblock %} {% block body %} <ul> {% for name in names %} <li>{{ name }}</li> {% endfor %} </ul> {% endblock %}
Twig šablóny majú zaužívanú príponu html.twig
. V šablóne prejdeme dáta ktoré sme dostali pomocou directívy for
. Všetky mená tak vygenerujeme do nezotriedeného listu. Twig používa {% %}
pre directívy, {# #}
pre komentáre a {{}}
pre output.
Zobrazenie namapovaných ciest
Máme vytvorené tri cesty. Všetky cesty si môžeme zobraziť pomocou Symfony console utility.
$ php bin/console debug:router -e prod --------- -------- -------- ------ ---------- Name Method Scheme Host Path --------- -------- -------- ------ ---------- home ANY ANY ANY /home colours ANY ANY ANY /colours names ANY ANY ANY /names --------- -------- -------- ------ ----------
Príkaz php bin/console debug:router -e prod
zobrazí nami vytvorené cesty. Keďže máme aktivovaný profiler a ten má vlastné cesty, pridali sme voľbu -e prod
, ktorá ich vynechá z výpisu.
V ďalšej časti sa budeme zaoberať request-response cyklom a prejdeme si ďalšie možnosti, ktoré nám ponúka AbstractController
.