Rutare
Routerul se ocupă de tot ce ține de adresele URL, astfel încât să nu mai trebuiască să vă gândiți la ele. Vom arăta:
- cum să setați routerul pentru ca URL-urile să fie conform așteptărilor
- vom vorbi despre SEO și redirecționare
- și vom arăta cum să scrieți propriul router
URL-urile mai prietenoase pentru oameni (sau și cool ori pretty URL) sunt mai utilizabile, mai ușor de reținut și contribuie pozitiv la SEO. Nette se gândește la asta și vine în întâmpinarea dezvoltatorilor. Puteți proiecta pentru aplicația dvs. exact structura de adrese URL pe care o doriți. Puteți chiar să o proiectați abia în momentul în care aplicația este deja finalizată, deoarece acest lucru se face fără intervenții în cod sau șabloane. Se definește într-un mod elegant într-un singur loc, în router, și nu este astfel împrăștiat sub formă de adnotări în toți presenterele.
Routerul din Nette este extraordinar prin faptul că este bidirecțional. Poate atât să decodeze URL-ul din cererea HTTP, cât și să creeze linkuri. Joacă, așadar, un rol esențial în Nette Application, deoarece decide ce presenter și acțiune vor executa cererea curentă, dar este utilizat și pentru generarea URL-urilor în șablon etc.
Totuși, routerul nu este limitat doar la această utilizare, îl puteți folosi în aplicații unde nu se utilizează deloc presentere, pentru API-uri REST etc. Mai multe în secțiunea utilizare independentă.
Colecție de rute
Cel mai plăcut mod de a defini forma adreselor URL în aplicație îl oferă clasa Nette\Application\Routers\RouteList. Definiția este formată dintr-o listă de așa-numite rute, adică măști de adrese URL și presenterele și acțiunile asociate acestora, folosind un API simplu. Rutele nu trebuie denumite în niciun fel.
$router = new Nette\Application\Routers\RouteList;
$router->addRoute('rss.xml', 'Feed:rss');
$router->addRoute('article/<id>', 'Article:view');
// ...
Exemplul spune că dacă deschidem în browser https://domain.com/rss.xml
, se va afișa presenterul
Feed
cu acțiunea rss
, dacă https://domain.com/article/12
, se va afișa presenterul
Article
cu acțiunea view
etc. În cazul în care nu se găsește o rută potrivită, Nette Application
reacționează aruncând excepția BadRequestException, care este
afișată utilizatorului ca o pagină de eroare 404 Not Found.
Ordinea rutelor
Ordinea în care sunt specificate rutele individuale este absolut crucială, deoarece acestea sunt evaluate secvențial de sus în jos. Se aplică regula conform căreia declarăm rutele de la cele specifice la cele generale:
// GREȘIT: 'rss.xml' este capturat de prima rută și înțelege acest șir ca <slug>
$router->addRoute('<slug>', 'Article:view');
$router->addRoute('rss.xml', 'Feed:rss');
// CORECT
$router->addRoute('rss.xml', 'Feed:rss');
$router->addRoute('<slug>', 'Article:view');
Rutele sunt evaluate de sus în jos și la generarea linkurilor:
// GREȘIT: linkul către 'Feed:rss' va fi generat ca 'admin/feed/rss'
$router->addRoute('admin/<presenter>/<action>', 'Admin:default');
$router->addRoute('rss.xml', 'Feed:rss');
// CORECT
$router->addRoute('rss.xml', 'Feed:rss');
$router->addRoute('admin/<presenter>/<action>', 'Admin:default');
Nu vom ascunde faptul că asamblarea corectă a rutelor necesită o anumită abilitate. Până când veți pătrunde în ea, panoul de rutare vă va fi un ajutor util.
Mască și parametri
Masca descrie calea relativă de la directorul rădăcină al site-ului. Cea mai simplă mască este un URL static:
$router->addRoute('products', 'Products:default');
Adesea, măștile conțin așa-numiții parametri. Aceștia sunt specificați între paranteze unghiulare (de ex.
<year>
) și sunt transmiși către presenterul țintă, de exemplu metodei renderShow(int $year)
sau parametrului persistent $year
:
$router->addRoute('chronicle/<year>', 'History:show');
Exemplul spune că dacă deschidem în browser https://example.com/chronicle/2020
, se va afișa presenterul
History
cu acțiunea show
și parametrul year: 2020
.
Parametrilor le putem specifica o valoare implicită direct în mască și astfel devin opționali:
$router->addRoute('chronicle/<year=2020>', 'History:show');
Ruta va accepta acum și URL-ul https://example.com/chronicle/
, care va afișa din nou History:show
cu parametrul year: 2020
.
Parametrul poate fi, desigur, și numele presenterului și al acțiunii. De exemplu, așa:
$router->addRoute('<presenter>/<action>', 'Home:default');
Ruta specificată acceptă, de ex., URL-uri de forma /article/edit
sau /catalog/list
și le
înțelege ca presentere și acțiuni Article:edit
și Catalog:list
.
În același timp, atribuie parametrilor presenter
și action
valorile implicite Home
și default
și sunt, prin urmare, și opționali. Deci, ruta acceptă și URL-uri de forma /article
și
le înțelege ca Article:default
. Sau invers, un link către Product:default
va genera calea
/product
, un link către Home:default
implicit va genera calea /
.
Masca poate descrie nu numai calea relativă de la directorul rădăcină al site-ului, ci și calea absolută, dacă începe cu un slash, sau chiar întregul URL absolut, dacă începe cu două slash-uri:
// relativ la document root
$router->addRoute('<presenter>/<action>', /* ... */);
// cale absolută (relativă la domeniu)
$router->addRoute('/<presenter>/<action>', /* ... */);
// URL absolut inclusiv domeniul (relativ la schemă)
$router->addRoute('//<lang>.example.com/<presenter>/<action>', /* ... */);
// URL absolut inclusiv schema
$router->addRoute('https://<lang>.example.com/<presenter>/<action>', /* ... */);
Expresii de validare
Pentru fiecare parametru se poate stabili o condiție de validare folosind o expresie regulată. De exemplu, pentru parametrul
id
specificăm că poate lua doar cifre folosind expresia regulată \d+
:
$router->addRoute('<presenter>/<action>[/<id \d+>]', /* ... */);
Expresia regulată implicită pentru toți parametrii este [^/]+
, adică totul cu excepția slash-ului. Dacă un
parametru trebuie să accepte și slash-uri, specificăm expresia .+
:
// acceptă https://example.com/a/b/c, path va fi 'a/b/c'
$router->addRoute('<path .+>', /* ... */);
Secvențe opționale
În mască se pot marca părți opționale folosind paranteze drepte. Orice parte a măștii poate fi opțională, în ea se pot afla și parametri:
$router->addRoute('[<lang [a-z]{2}>/]<name>', /* ... */);
// Acceptă căi:
// /cs/download => lang => cs, name => download
// /download => lang => null, name => download
Când un parametru face parte dintr-o secvență opțională, devine, desigur, și el opțional. Dacă nu are specificată o valoare implicită, atunci va fi null.
Părțile opționale pot fi și în domeniu:
$router->addRoute('//[<lang=en>.]example.com/<presenter>/<action>', /* ... */);
Secvențele pot fi imbricate și combinate liber:
$router->addRoute(
'[<lang [a-z]{2}>[-<sublang>]/]<name>[/page-<page=0>]',
'Home:default',
);
// Acceptă căi:
// /cs/hello
// /en-us/hello
// /hello
// /hello/page-12
La generarea URL-ului, se urmărește varianta cea mai scurtă, deci tot ce poate fi omis se omite. De aceea, de exemplu, ruta
index[.html]
generează calea /index
. Inversarea comportamentului este posibilă prin specificarea unui
semn de exclamare după paranteza dreaptă de deschidere:
// acceptă /hello și /hello.html, generează /hello
$router->addRoute('<name>[.html]', /* ... */);
// acceptă /hello și /hello.html, generează /hello.html
$router->addRoute('<name>[!.html]', /* ... */);
Parametrii opționali (adică parametrii care au o valoare implicită) fără paranteze drepte se comportă în esență ca și cum ar fi încadrați în paranteze în felul următor:
$router->addRoute('<presenter=Home>/<action=default>/<id=>', /* ... */);
// corespunde acestuia:
$router->addRoute('[<presenter=Home>/[<action=default>/[<id>]]]', /* ... */);
Dacă am dori să influențăm comportamentul slash-ului final, astfel încât, de ex., în loc de /home/
să se
genereze doar /home
, acest lucru se poate realiza astfel:
$router->addRoute('[<presenter=Home>[/<action=default>[/<id>]]]', /* ... */);
Substituenți
În masca căii absolute putem folosi următorii substituenți și evita astfel, de ex., necesitatea de a scrie în mască domeniul, care se poate diferenția în mediul de dezvoltare și cel de producție:
%tld%
= top level domain, de ex.com
sauorg
%sld%
= second level domain, de ex.example
%domain%
= domeniu fără subdomenii, de ex.example.com
%host%
= întregul host, de ex.www.example.com
%basePath%
= calea către directorul rădăcină
$router->addRoute('//www.%domain%/%basePath%/<presenter>/<action>', /* ... */);
$router->addRoute('//www.%sld%.%tld%/%basePath%/<presenter>/<action', /* ... */);
Notație extinsă
Ținta rutei, de obicei scrisă sub forma Presenter:action
, poate fi scrisă și folosind un array care definește
parametrii individuali și valorile lor implicite:
$router->addRoute('<presenter>/<action>[/<id \d+>]', [
'presenter' => 'Home',
'action' => 'default',
]);
Pentru o specificație mai detaliată, se poate utiliza o formă și mai extinsă, unde, pe lângă valorile implicite, putem
seta și alte proprietăți ale parametrilor, cum ar fi expresia regulată de validare (vezi parametrul id
):
use Nette\Routing\Route;
$router->addRoute('<presenter>/<action>[/<id>]', [
'presenter' => [
Route::Value => 'Home',
],
'action' => [
Route::Value => 'default',
],
'id' => [
Route::Pattern => '\d+',
],
]);
Este important de menționat că, dacă parametrii definiți în array nu sunt specificați în masca căii, valorile lor nu pot fi modificate, nici prin parametrii query specificați după semnul întrebării în URL.
Filtre și traduceri
Codul sursă al aplicației îl scriem în engleză, dar dacă site-ul trebuie să aibă URL-uri în română, atunci rutarea simplă de tipul:
$router->addRoute('<presenter>/<action>', 'Home:default');
va genera URL-uri în engleză, cum ar fi /product/123
sau /cart
. Dacă dorim ca presenterele și
acțiunile să fie reprezentate în URL prin cuvinte românești (de ex. /produs/123
sau /cos
), putem
utiliza un dicționar de traducere. Pentru scrierea sa avem nevoie deja de varianta “mai vorbăreață” a celui de-al doilea
parametru:
use Nette\Routing\Route;
$router->addRoute('<presenter>/<action>', [
'presenter' => [
Route::Value => 'Home',
Route::FilterTable => [
// șir în URL => presenter
'produs' => 'Product',
'cos' => 'Cart',
'catalog' => 'Catalog',
],
],
'action' => [
Route::Value => 'default',
Route::FilterTable => [
'lista' => 'list',
],
],
]);
Mai multe chei ale dicționarului de traducere pot duce la același presenter. Astfel se creează diferite aliasuri pentru acesta. Ca variantă canonică (adică cea care va fi în URL-ul generat) se consideră ultima cheie.
Tabelul de traducere poate fi utilizat în acest mod pentru orice parametru. În același timp, dacă traducerea nu există, se
ia valoarea originală. Acest comportament poate fi schimbat prin adăugarea Route::FilterStrict => true
și ruta
va respinge apoi URL-ul dacă valoarea nu se află în dicționar.
Pe lângă dicționarul de traducere sub formă de array, se pot implementa și funcții de traducere proprii.
use Nette\Routing\Route;
$router->addRoute('<presenter>/<action>/<id>', [
'presenter' => [
Route::Value => 'Home',
Route::FilterIn => function (string $s): string { /* ... */ },
Route::FilterOut => function (string $s): string { /* ... */ },
],
'action' => 'default',
'id' => null,
]);
Funcția Route::FilterIn
convertește între parametrul din URL și șirul care este apoi transmis presenterului,
funcția FilterOut
asigură conversia în sens invers.
Parametrii presenter
, action
și module
au deja filtre predefinite care convertesc
între stilul PascalCase respectiv camelCase și kebab-case utilizat în URL. Valoarea implicită a parametrilor se scrie deja în
forma transformată, deci, de exemplu, în cazul presenterului scriem <presenter=ProductEdit>
, nu
<presenter=product-edit>
.
Filtre generale
Pe lângă filtrele destinate parametrilor specifici, putem defini și filtre generale, care primesc un array asociativ al
tuturor parametrilor, pe care îi pot modifica în orice mod și apoi îi returnează. Filtrele generale le definim sub cheia
null
.
use Nette\Routing\Route;
$router->addRoute('<presenter>/<action>', [
'presenter' => 'Home',
'action' => 'default',
null => [
Route::FilterIn => function (array $params): array { /* ... */ },
Route::FilterOut => function (array $params): array { /* ... */ },
],
]);
Filtrele generale oferă posibilitatea de a modifica comportamentul rutei în absolut orice mod. Le putem folosi, de exemplu,
pentru modificarea parametrilor pe baza altor parametri. De exemplu, traducerea <presenter>
și
<action>
pe baza valorii curente a parametrului <lang>
.
Dacă un parametru are definit un filtru propriu și, în același timp, există un filtru general, se execută filtrul propriu
FilterIn
înainte de cel general și, invers, filtrul general FilterOut
înainte de cel propriu. Deci,
în interiorul filtrului general, valorile parametrilor presenter
respectiv action
sunt scrise în
stilul PascalCase respectiv camelCase.
Rute unidirecționale (OneWay)
Rutele unidirecționale sunt utilizate pentru a menține funcționalitatea URL-urilor vechi, pe care aplicația nu le mai
generează, dar le acceptă în continuare. Le marcăm cu flag-ul OneWay
:
// URL vechi /product-info?id=123
$router->addRoute('product-info', 'Product:detail', $router::ONE_WAY);
// URL nou /product/123
$router->addRoute('product/<id>', 'Product:detail');
La accesarea URL-ului vechi, presenterul redirecționează automat către noul URL, astfel încât motoarele de căutare nu vă vor indexa aceste pagini de două ori (vezi SEO și canonizare).
Rutare dinamică cu callback-uri
Rutarea dinamică cu callback-uri vă permite să atribuiți rutelor direct funcții (callback-uri), care se execută atunci când calea respectivă este vizitată. Această funcționalitate flexibilă vă permite să creați rapid și eficient diferite puncte finale (endpoints) pentru aplicația dvs.:
$router->addRoute('test', function () {
echo 'sunteți la adresa /test';
});
Puteți defini, de asemenea, parametri în mască, care se vor transmite automat către callback-ul dvs.:
$router->addRoute('<lang cs|en>', function (string $lang) {
echo match ($lang) {
'cs' => 'Bun venit la versiunea română a site-ului nostru!',
'en' => 'Welcome to the English version of our website!',
};
});
Module
Dacă avem mai multe rute care aparțin unui modul comun, utilizăm
withModule()
:
$router = new RouteList;
$router->withModule('Forum') // următoarele rute fac parte din modulul Forum
->addRoute('rss', 'Feed:rss') // presenterul va fi Forum:Feed
->addRoute('<presenter>/<action>')
->withModule('Admin') // următoarele rute fac parte din modulul Forum:Admin
->addRoute('sign:in', 'Sign:in');
O alternativă este utilizarea parametrului module
:
// URL manage/dashboard/default se mapează pe presenterul Admin:Dashboard
$router->addRoute('manage/<presenter>/<action>', [
'module' => 'Admin',
]);
Subdomenii
Colecțiile de rute le putem împărți după subdomenii:
$router = new RouteList;
$router->withDomain('example.com')
->addRoute('rss', 'Feed:rss')
->addRoute('<presenter>/<action>');
În numele domeniului se pot folosi și substituenți:
$router = new RouteList;
$router->withDomain('example.%tld%')
// ...
Prefix de cale
Colecțiile de rute le putem împărți după calea din URL:
$router = new RouteList;
$router->withPath('eshop')
->addRoute('rss', 'Feed:rss') // prinde URL /eshop/rss
->addRoute('<presenter>/<action>'); // prinde URL /eshop/<presenter>/<action>
Combinații
Împărțirile menționate mai sus pot fi combinate între ele:
$router = (new RouteList)
->withDomain('admin.example.com')
->withModule('Admin')
->addRoute(/* ... */)
->addRoute(/* ... */)
->end()
->withModule('Images')
->addRoute(/* ... */)
->end()
->end()
->withDomain('example.com')
->withPath('export')
->addRoute(/* ... */)
// ...
Parametri query
Măștile pot conține și parametri query (parametri după semnul întrebării în URL). Acestora nu li se poate defini o expresie de validare, dar li se poate schimba numele sub care sunt transmiși presenterului:
// parametrul query 'cat' dorim să îl folosim în aplicație sub numele 'categoryId'
$router->addRoute('product ? id=<productId> & cat=<categoryId>', /* ... */);
Parametri Foo
Acum intrăm mai în profunzime. Parametrii Foo sunt în esență parametri nedenumiți care permit potrivirea unei expresii
regulate. Un exemplu este o rută care acceptă /index
, /index.html
, /index.htm
și
/index.php
:
$router->addRoute('index<? \.html?|\.php|>', /* ... */);
Se poate, de asemenea, defini explicit șirul care va fi utilizat la generarea URL-ului. Șirul trebuie plasat direct după
semnul întrebării. Următoarea rută este similară cu cea anterioară, dar generează /index.html
în loc de
/index
, deoarece șirul .html
este setat ca valoare de generare:
$router->addRoute('index<?.html \.html?|\.php|>', /* ... */);
Integrarea în aplicație
Pentru a integra routerul creat în aplicație, trebuie să îi spunem despre el containerului DI. Cea mai ușoară cale este
să pregătim o fabrică care va produce obiectul routerului și să comunicăm în configurația containerului că trebuie să
o folosească. Să presupunem că în acest scop scriem metoda App\Core\RouterFactory::createRouter()
:
namespace App\Core;
use Nette\Application\Routers\RouteList;
class RouterFactory
{
public static function createRouter(): RouteList
{
$router = new RouteList;
$router->addRoute(/* ... */);
return $router;
}
}
În configurație scriem apoi:
services:
- App\Core\RouterFactory::createRouter
Orice dependențe, de exemplu de baza de date etc., sunt transmise metodei fabricii ca parametri ai săi folosind autowiring-ul:
public static function createRouter(Nette\Database\Connection $db): RouteList
{
// ...
}
SimpleRouter
Un router mult mai simplu decât colecția de rute este SimpleRouter. Îl folosim atunci
când nu avem cerințe speciale privind forma URL-ului, dacă nu este disponibil mod_rewrite
(sau alternativele sale)
sau dacă deocamdată nu dorim să ne ocupăm de URL-uri frumoase.
Generează adrese aproximativ în această formă:
http://example.com/?presenter=Product&action=detail&id=123
Parametrul constructorului SimpleRouter este presenterul & acțiunea implicită către care trebuie direcționat dacă
deschidem pagina fără parametri, de ex. http://example.com/
.
// presenterul implicit va fi 'Home' și acțiunea 'default'
$router = new Nette\Application\Routers\SimpleRouter('Home:default');
Recomandăm definirea directă a SimpleRouter în configurație:
services:
- Nette\Application\Routers\SimpleRouter('Home:default')
SEO și canonizare
Framework-ul contribuie la SEO (optimizarea găsirii pe internet) prin prevenirea duplicării conținutului la URL-uri
diferite. Dacă către o anumită țintă duc mai multe adrese, de ex. /index
și /index.html
,
framework-ul o determină pe prima dintre ele ca fiind primară (canonică) și le redirecționează pe celelalte către ea
folosind codul HTTP 301. Datorită acestui fapt, motoarele de căutare nu vă indexează paginile de două ori și nu le
diluează page rank-ul.
Acest proces se numește canonizare. URL-ul canonic este cel generat de router, adică prima rută corespunzătoare din colecție fără flag-ul OneWay. De aceea, în colecție specificăm rutele primare primele.
Canonizarea este efectuată de presenter, mai multe în capitolul canonizare.
HTTPS
Pentru a putea utiliza protocolul HTTPS, este necesar să îl activați pe hosting și să configurați corect serverul.
Redirecționarea întregului site către HTTPS trebuie setată la nivelul serverului, de exemplu folosind fișierul .htaccess în directorul rădăcină al aplicației noastre, și anume cu codul HTTP 301. Setarea poate varia în funcție de hosting și arată aproximativ așa:
<IfModule mod_rewrite.c>
RewriteEngine On
...
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
...
</IfModule>
Routerul generează URL-uri cu același protocol cu care a fost încărcată pagina, deci nu este nevoie să setați nimic în plus.
Dacă însă, în mod excepțional, avem nevoie ca diferite rute să ruleze sub protocoale diferite, îl specificăm în masca rutei:
// Va genera adresa cu HTTP
$router->addRoute('http://%host%/<presenter>/<action>', /* ... */);
// Va genera adresa cu HTTPs
$router->addRoute('https://%host%/<presenter>/<action>', /* ... */);
Depanarea routerului
Panoul de rutare afișat în Tracy Bar este un ajutor util, care afișează lista rutelor și, de asemenea, parametrii pe care routerul i-a obținut din URL.
Bara verde cu simbolul ✓ reprezintă ruta care a procesat URL-ul curent, cu albastru și simbolul ≈ sunt marcate rutele care ar procesa și ele URL-ul, dacă cea verde nu le-ar fi devansat. În continuare vedem presenterul & acțiunea curentă.

În același timp, dacă are loc o redirecționare neașteptată din cauza canonizării, este util să vă uitați în panoul din bara redirect, unde veți afla cum a înțeles routerul inițial URL-ul și de ce a redirecționat.
La depanarea routerului, recomandăm deschiderea în browser a Developer Tools (Ctrl+Shift+I sau Cmd+Option+I) și în panoul Network dezactivarea cache-ului, pentru a nu se salva în el redirecționările.
Performanță
Numărul de rute influențează viteza routerului. Numărul lor nu ar trebui să depășească în niciun caz câteva zeci. Dacă site-ul dvs. are o structură URL prea complicată, puteți scrie un router personalizat.
Dacă routerul nu are dependențe, de exemplu de baza de date, și fabrica sa nu acceptă niciun argument, putem serializa forma sa compilată direct în containerul DI și astfel accelera ușor aplicația.
routing:
cache: true
Router personalizat
Următoarele rânduri sunt destinate utilizatorilor foarte avansați. Puteți crea un router propriu și să îl integrați complet natural în colecția de rute. Routerul este o implementare a interfeței Nette\Routing\Router cu două metode:
use Nette\Http\IRequest as HttpRequest;
use Nette\Http\UrlScript;
class MyRouter implements Nette\Routing\Router
{
public function match(HttpRequest $httpRequest): ?array
{
// ...
}
public function constructUrl(array $params, UrlScript $refUrl): ?string
{
// ...
}
}
Metoda match
procesează cererea curentă $httpRequest, din
care se poate obține nu numai URL-ul, ci și antetele etc., într-un array care conține numele presenterului și parametrii
săi. Dacă nu poate procesa cererea, returnează null. La procesarea cererii, trebuie să returnăm cel puțin presenterul și
acțiunea. Numele presenterului este complet și conține și eventualele module:
[
'presenter' => 'Front:Home',
'action' => 'default',
]
Metoda constructUrl
, dimpotrivă, asamblează din array-ul de parametri URL-ul absolut rezultat. Pentru aceasta
poate utiliza informații din parametrul $refUrl
, care este URL-ul curent.
În colecția de rute îl adăugați folosind add()
:
$router = new Nette\Application\Routers\RouteList;
$router->add($myRouter);
$router->addRoute(/* ... */);
// ...
Utilizare independentă
Prin utilizare independentă înțelegem utilizarea capacităților routerului într-o aplicație care nu utilizează Nette Application și presentere. Se aplică aproape tot ce am arătat în acest capitol, cu aceste diferențe:
- pentru colecții de rute folosim clasa Nette\Routing\RouteList
- ca simple router clasa Nette\Routing\SimpleRouter
- deoarece nu există perechea
Presenter:action
, folosim notația extinsă
Deci, din nou, creăm o metodă care ne va asambla routerul, de ex.:
namespace App\Core;
use Nette\Routing\RouteList;
class RouterFactory
{
public static function createRouter(): RouteList
{
$router = new RouteList;
$router->addRoute('rss.xml', [
'controller' => 'RssFeedController',
]);
$router->addRoute('article/<id \d+>', [
'controller' => 'ArticleController',
]);
// ...
return $router;
}
}
Dacă utilizați un container DI, ceea ce recomandăm, din nou adăugăm metoda în configurație și apoi obținem routerul împreună cu cererea HTTP din container:
$router = $container->getByType(Nette\Routing\Router::class);
$httpRequest = $container->getByType(Nette\Http\IRequest::class);
Sau creăm obiectele direct:
$router = App\Core\RouterFactory::createRouter();
$httpRequest = (new Nette\Http\RequestFactory)->fromGlobals();
Acum rămâne doar să punem routerul la treabă:
$params = $router->match($httpRequest);
if ($params === null) {
// nu a fost găsită o rută corespunzătoare, trimitem eroarea 404
exit;
}
// procesăm parametrii obținuți
$controller = $params['controller'];
// ...
Și invers, folosim routerul pentru a asambla un link:
$params = ['controller' => 'ArticleController', 'id' => 123];
$url = $router->constructUrl($params, $httpRequest->getUrl());