Přejít k navigační liště

Zdroják » PHP » Symfony po krůčkách – Routing

Symfony po krůčkách – Routing

Články PHP

Hezké URL jsou ve světě webových aplikací v dnešní době již v podstatě nutností. Dnešní díl přivádí pod světla ramp Symfony komponentu Routing, díky které je práce s hezkými URL a jejich správa opravdu jednoduchá a elegantní. Dnes si ukážeme základní principy routování v Symfony.

Nálepky:

Routing nám slouží ke 2 základním úkolům:

  1. Na URL namapuje pojmenovanou sadu konfiguračních parametrů (tzv. routa), podle kterých může aplikace provést konkrétní akce. (Např. 'marketing/article/new' => 'article_new').
  2. Na základě routy generuje URL. (Tzn. opačný směr 'article_new' => 'marketing/article/new').

Příklad na začátek

Komponentu lze nainstalovat pomocí Composeru:

composer require symfony/routing

Pro úplný základ routování jsou potřeba 3 části:

  1. RouteCollection – obsahuje kolekci rout (routa je představována třídou Route).
  2. RequestContext – obsahuje informace o aktuálním requestu.
  3. UrlMatcher – provádí mapování requestu na konkrétní routu.

Jak spolu jednotlivé části fungují, lze vidět na jednoduchém příkladu:

use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

require_once __DIR__ . '/vendor/autoload.php';

$route = new Route('/hello', ['controller' => 'GreetingController']); 

$routeCollection = new RouteCollection();
$routeCollection->add('greeting', $route);

$requestContext = new RequestContext('/');

$urlMatcher = new UrlMatcher($routeCollection, $requestContext);

$parameters = $urlMatcher->match('/hello');
var_dump($parameters);
// ['controller' => 'GreetingController', '_route' => 'greeting']

Stačí nám 3 důležité třídy

Route – co kam vede

Třída Route přebírá jako první parametr v konstruktoru textový řetězec obsahující část URL za doménou, tzv. URL path. Jako druhý parametr se předává pole proměnných, které může obsahovat cokoliv, co logika vaší aplikace vyžaduje ke zpracování požadavku. Zde je kupříkladu definován kontrolér, protože Symfony stojí na MVC architektuře a aplikace potřebuje vědět, který kontrolér se má o požadavek postarat.

RouteCollection – když je jich víc

Pomocí metody RouteCollection::add() lze do kolekce přidávat libovolné množství rout. Metoda má dva argumenty, první je název routy, druhý je instance třídy Route.

UrlMatcher – volba té pravé

Metoda UrlMatcher:match() pak hledá routu na základě URL a pokud takovou nalezne, vrací pole parametrů dané routy rozšířené o její název pod klíčem _route. Pokud není nalezena žádná odpovídající routa, je vyhozena výjimka ResourceNotFoundException a my můžeme uživateli vrátit například 404 stránku.

Vytváříme Routu

Nejčastěji budete pravděpodobně využívat první 2 argumenty konstruktoru:

  • na prvním místě URL path, která může obsahovat placeholdery pro dynamickou část tvořenou parametry routy (např. article/edit/{articleId})
  • na druhém místě se pak nastavuje pole výchozích hodnot, které je vráceno v případě, že request odpovídá dané routě

$route = new Route('/hello', ['controller' => 'GreetingController']);

Zajímavý je poslední parametr $condition – podmínka, která musí být vyhodnocena jako pravdivá, aby byla routa rozpoznána. K čemu slouží ostatní parametry, lze nastudovat v dokumentaci.

Vytváříme RequestContext

RequestContext má v sobě informace o aktuálním requestu, které můžeme definovat pomocí parametrů konstruktoru. Všechny potřebné údaje lze získat z globální proměnné $_SERVER, ale elegantnějším řešením je použití Symfony komponenty HttpFoundation a její třídy Request. RequestContext pak vytvoříme následujícím způsobem:

use Symfony\Component\HttpFoundation\Request;   

$context = new RequestContext(); 
$context->fromRequest(Request::createFromGlobals());

Generujeme URL

Symfony poskytuje jednoduchý nástroj pro generování URL pro danou routu, a tím je třída UrlGenerator. Jeho použití je opravdu přímočaré:

use Symfony\Component\Routing\Generator\UrlGenerator;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

require_once __DIR__ . '/vendor/autoload.php';

$routes = new RouteCollection();
$routes->add('article_edit', new Route('/article/edit/{articleId}'));

$context = new RequestContext('/');

$generator = new UrlGenerator($routes, $context);

$url = $generator->generate('article_edit', ['articleId' => 1]);
var_dump($url);
// /article/edit/1

Metoda UrlGenerator::generate() přebírá:

  • 1. parametr název routy,
  • na 2. místě pole parametrů
  • a 3. parametrem si můžeme určit, zda chceme generovat cestu absolutní nebo relativní.

Další způsoby definování rout

Už jsme si ukázali, že routy do kolekce můžeme přidávat pomocí metody RouteCollection::add(). To ale rozhodně není jediný způsob. Podívejme se na další možnosti, jak definovat routy v naší aplikaci:

  • Definice v souboru – routy můžeme definovat v konfiguračních yml nebo xml souborech. Definice routy v yml může vypadat např. takto:
# routes.yml
article_edit:
path: /article/edit/{articleId}
defaults: { _controller: ArticleController::editAction }
requirements:
    articleId: \d+

Pro načtení definice využijeme YamlFileLoader. Aby tento příklad fungoval, je potřeba mít nainstalované Symfony komponenty Config a Yaml (composer require symfony/config symfony/yaml).

use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\YamlFileLoader;

require_once __DIR__ . '/vendor/autoload.php';

$locator = new FileLocator(__DIR__);
$loader = new YamlFileLoader($locator);
$routeCollection = $loader->load('routes.yml');

Jak to vše poskládat dohromady?

Jednoduše! Součástí Routing komponenty je třída Router, která vše zaobaluje a představuje tak krásný příklad integrace jednotlivých částí routovacího systému v Symfony.

use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\YamlFileLoader;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\Router;

require_once __DIR__ . '/vendor/autoload.php';

$locator = new FileLocator(__DIR__);
$requestContext = new RequestContext();

$router = new Router(
    new YamlFileLoader($locator),
   'routes.yml',
   [],
   $requestContext
);
$route = $router->match('/article/edit/1');
var_dump($route);
// ['_controller' => 'ArticleController::editAction', 'articleId' => '1', '_route' => 'article_edit']

$url = $router->generate('article_edit', ['articleId' => 1]);
var_dump($url);
// '/article/edit/1'

Zase o krok dále

Dnes jsme si ukázali:

  • co je to routa,
  • k čemu slouží routování a jak to v Symfony funguje,
  • jak generovat URL adresy,
  • jakými způsoby lze definovat routy v aplikaci.

Komentáře

Odebírat
Upozornit na
guest
3 Komentářů
Nejstarší
Nejnovější Most Voted
lenoch

Zajímavý seriál, děkuji, doufám, že bude pokračovat.
Zeptám se: Má symfony také nějaké komponenty pro zjednodušení tvorby a zpracování datagridu a formuláře? To mě totiž většinou nejvíc pálí a mám pocit, že fw to nijak zvlášť nepodporují. Obyčejně existují nějaké externí pluginy, které ne vždycky fungují, různé paginatory např., ale kompletní datagrid s řazením apod. nic moc. Má to symfony?

Dennis Fridrich
lenoch

Vypadá zajímavě – prozkoumám to, děkuji.

Frugal computing: architektura pro dobu dražší infrastruktury

Vývojáři se naučili zrychlovat dotazy, přidávat cache, škálovat služby a hlídat účet za cloud. Frugal computing začíná o jednu otázku dřív: musí se výpočet, přesun dat, volání modelu nebo uložení vůbec stát? Rostoucí spotřeba datových center a nové evropské reportování ho posouvají do návrhu architektury, dřív než do závěrečné poznámky o udržitelnosti v prezentaci.

Odysseus: PewDiePie vydal open-source AI workspace, který běží na vašem vlastním hardwaru

AI
Komentáře: 0
Felix Kjellberg, youtuber se 110 miliony odběratelů, strávil rok učením se programovat a fine-tuningem vlastních AI modelů. Výsledkem je Odysseus – bezplatný, open-source workspace pro práci s umělou inteligencí, který neposílá žádná data do cloudu. Projekt má týden, přes 61 000 hvězdiček na GitHubu a znovu otevírá otázku, komu vlastně patří váš digitální kontext.

Když Git už nestačí: jak izolovat databázový stav pro pokusy AI agentů

Gitová větev vývojářům oddělí kód, ale databáze často zůstává společná. U AI agentů je to slabé místo: rychle spouštějí migrace, mění data a zkoušejí víc cest najednou. Databázová větev jim dá vlastní pracovní prostor, jenže tím práce nekončí. Ještě je potřeba řešit citlivá data, oprávnění, životnost větve i zbytek stavu aplikace.