Lekce 3 - Směrovač (router)
V minulé lekci, .htaccess, autoloader a obecný kontroler, jsme si nastavili .htaccess, vytvořili index.php a obecný kontroler.
Dnes se budeme věnovat směrovači, tedy komponentě, která podle URL adresy nasměruje požadavek na správný kontroler.
Směrovač
Směrovač (anglicky router) dostane URL adresu, kterou si zpracuje a na jejím základě zavolá příslušný kontroler. Opět je několik způsobů, kterými lze směrovač implementovat a opět jsem vybral ten nejjednodušší. Princip směrovače nápadně připomíná princip kontroleru, toho také využijeme, směrovač bude kontroler.
Směrovač tedy přidáme jako kontroler. Ve složce kontrolery/
vytvoříme soubor SmerovacKontroler.php a do něj stejnojmennou
třídu, která bude dědit z obecné třídy Kontroler, kterou
jsme si udělali minule. Nezapomeneme implementovat abstraktní metodu
zpracuj().
Směrovač dle adresy zjistí, který kontroler voláme, vytvoří nám ho a
zároveň i uloží do atributu $kontroler, který třídě
rovněž přidáme.
<?php class SmerovacKontroler extends Kontroler { protected Kontroler $kontroler; public function zpracuj(array $parametry): void { } }
Možná je trochu matoucí, že v sobě máme vlastně vložené 2
kontrolery, ale je to tak. Kontroler SmerovacKontroler bere URL od
uživatele, tu zpracuje a podle ní zavolá příslušný vložený kontroler
(např. ClanekKontroler). Oba kontrolery budou mít pohled,
SmerovacKontroler bude mít šablonu s rozložením stránky
(hlavička, menu atd.) a vložený kontroler bude mít šablonu s obsahem dané
stránky (článek, kontaktní formulář, přihlašovací obrazovka atd.).
Parsování URL adresy
Jako první si naparsujeme URL adresu a to přímo v PHP. Adresa nám přijde jako textový řetězec, bude vypadat stejně, jako ta v adresním řádku. Pojďme se dohodnout nejprve na jejím formátu, který bude následující a který jsme již minule naťukli:
http://www.domena.cz/kontroler/parametr2/parametr3
V praxi by vypadala třeba takto:
http://www.domena.cz/clanek/nazev-clanku
Říkáme, že voláme kontroler ClanekKontroler a předáváme
mu parametr "nazev-clanku". Kontroler si už článek vezme od modelu a předá
ho pohledu, který ho vypíše uživateli.
Např. z této URL:
http://www.domena.cz/kontroler/parametr2/parametr3
bychom potřebovali získat takového pole:
Array
(
[0] => kontroler
[1] => parametr2
[2] => parametr3
)
Přijdeme třídě tedy metodu parsujURL(), která bude jako
argument přijímat URL adresu a vrátí nám výše zmíněné pole:
private function parsujURL(string $url) : array { }
K naparsování url adresy nám PHP poskytuje funkci
parse_url(), která za nás sice neudělá všechnu práci, ale
pomůže nám oddělit část s protokolem a doménou od části s parametry.
Funkce vrátí asociativní pole, část
/kontroler/parametr2/parametr3 dostaneme pod indexem
path. Pozor si dáme jen na "/", kterým může tato část
začínat, pokud tam je, jednoduše ho odstraníme pomocí funkce
ltrim(). Odstraníme také bílé znaky kolem URL (kdyby za ni
třeba někdo napsal mezeru), k tomu slouží PHP funkce
trim().
$naparsovanaURL = parse_url($url); $naparsovanaURL["path"] = ltrim($naparsovanaURL["path"], "/"); $naparsovanaURL["path"] = trim($naparsovanaURL["path"]);
Nyní není nic jednoduššího, než si výsledný řetězec rozbít podle lomítek na pole jednotlivých parametrů:
$rozdelenaCesta = explode("/", $naparsovanaURL["path"]);
Výsledek vrátíme a funkce k parsování URL je hotová:
return $rozdelenaCesta;
Volání vloženého kontroleru
Přesuňme se do metody zpracuj(), která se nám na začátku
požadavku zavolá. V argumentu $parametry budeme očekávat pole,
kde na 1. indexu bude URL adresa. Tu si naparsujeme pomocí naší metody:
$naparsovanaURL = $this->parsujURL($parametry[0]);
Zatím nebudeme ošetřovat případy, kdy je URL zadána nekompletní nebo neexistující.
Získání názvu třídy
První úkol bude zjistit jméno třídy kontroleru. Již víme, že název
kontroleru je 1. parametr v naparsované URL adrese. Pro URL adresy však platí
jiné konvence, než pro názvy tříd. Proto nám název kontroleru přijde
jako nazev-kontroleru a my z něj potřebujeme vytvořit
NazevKontroleruKontroler, tedy např. řetězec clanek
převedeme na ClanekKontroler a vypis-uzivatelu na
VypisUzivateluKontroler. Na tento převod si opět vytvoříme ve
třídě metodu a pojmenujeme ji pomlckyDoVelbloudiNotace(). Metoda
bude přijímat i vracet řetězec:
private function pomlckyDoVelbloudiNotace(string $text): string { }
Použijeme PHP funkci ucwords(), která zvětší počáteční
písmeno všech slov ve větě. Funkce sice není UTF-safe, ale to nám zde
nevadí. Z parametru si tedy nejprve uděláme větu a to jednoduše tak, že
pomlčky nahradíme mezerami:
$veta = str_replace('-', ' ', $text);
Následně zvětšíme první písmena slov a mezery odstraníme:
$veta = ucwords($veta); $veta = str_replace(' ', '', $veta);
To je vše. Kód by šel napsat i do jednoho řádku, ale pro potřeby
tutoriálu jsem ho rozepsal. Metoda převede např. řetězec
vypis-uzivatelu na VypisUzivatelu. Výsledek
navrátíme:
return $veta;
Vraťme se do metody zpracuj() a zjistěme si název třídy
kontroleru pomocí naší nové metody:
$tridaKontroleru = $this->pomlckyDoVelbloudiNotace(array_shift($naparsovanaURL)) . 'Kontroler';
Pomocí array_shift() jsme získali 1. parametr z naparsované
URL a zároveň ho z tohoto pole i odstranili, již ho tam totiž nebudeme
potřebovat.
Název třídy kontroleru si pro testovací účely pouze vypišme:
echo($tridaKontroleru);
Stejně tak si vypišme i zbytek pole z URL adresy:
echo('<br />'); print_r($naparsovanaURL);
Volání směrovače
Přesuňme se do index.php a vytvořme si zde směrovač.
Necháme ho zpracovat URL adresu, kterou v PHP nalezneme v superglobálním poli
$_SERVER pod klíčem REQUEST_URI. Hodnotu ještě
musíme vložit do pole, jelikož to metoda zpracuj()
očekává:
$smerovac = new SmerovacKontroler(); $smerovac->zpracuj(array($_SERVER['REQUEST_URI']));
Díky autoloaderu z minula se nám třída SmerovacKontroler
sama načte. Celou magii si vyzkoušíme, zadáme následující URL:
localhost/clanek/nazev-clanku/dalsi-parametr
A měli bychom dosáhnout následujícího výsledku:
Směrovač nám tedy funguje, z URL adresy nám zjistil název kontroleru a pole parametrů. Pro dnešek toho již bylo dost.
Příště, v lekci Propojení kontroleru a pohledu, si propojíme pohled s kontrolerem.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 3664x (4.4 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP

David se informační technologie naučil na