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ší Nejvíce hlasů
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.

Zahoďte knihovny: dropdowny, tooltipy a přechody stránek jen s HTML a CSS

Rozbalovací menu, tooltip, modální okno a plynulý přechod mezi stránkami. Ještě nedávno čtyři důvody, proč do projektu přidat několik knihoven a desítky kilobajtů JavaScriptu. V roce 2026 už to všechno zvládne prohlížeč sám. Ukážeme si, jak na to s Popover API, CSS anchor positioningem a View Transitions, a také kde mají své limity.

Rok po Shai-Hulud: co se změnilo na npm a co musíte udělat do ledna

Před rokem začal registrem npm procházet samošířící červ Shai-Hulud. Od té doby se útoky na dodavatelský řetězec JavaScriptu staly pravidelnou záležitostí a npm postupně přepisuje pravidla publikování. Projdeme, co se za ten rok stalo, jak dnes bezpečně publikovat balíček, co musíte stihnout do ledna 2027 a jak se bránit jako uživatel balíčků.

Vercel zrychlil směrování v CDN. Překvapivě pomohly menší bloky

Vercel zrychlil směrování v CDN tím, že začal načítat víc dat najednou. U velkých webů mu po každém nasazení scházely v cache údaje o mnoha jednotlivých cestách, takže je musel opakovaně dohledávat. U nových bloků metadat Vercel naměřil o 91 % kratší dobu tohoto hledání v 99. percentilu. Cesta k výsledku ale vedla přes nečekané zjištění: příliš velký blok se při vyřizování požadavků nevyplatil.