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 3630x (4.4 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP