Router

Kvůli dlouhému obsahu jsem stránku Další možnosti rozdělila na samostatné části:


Adresy složené z parametrů

Pokud nepoužíváte na svém webu "pěkné URL" ale adresy složené z párů parametr+hodnota a např. kvůli vysoké návštěvnosti to nechcete měnit, router je připraven i na tuto situaci. Syntax rout se tím zjednoduší - stačí vyjmenovat jednotlivé parametry.

Chceme např. definovat routu pro adresu www.example.com/?action=vthread&forum=3&topic=123456&page=3. Parametry forum, topic a page musí být složené z čísel a poslední dva z nich jsou nepovinné:

$router = new Router;
$router->addRoute(':action, :forum<\\d+>, :?topic<\\d+>, :?page<\\d+>', array(), Route::SIMPLE);

$router->parseUrl($_SERVER['QUERY_STRING']);

Modifikátorem Route::SIMPLE řekneme routeru, že bude pracovat s tímto typem adres. Interně tedy místo třídy Route použije odvozenou třídu SimpleRoute. U alternativního zápisu rout je to lépe vidět:

$router[] = new SimpleRoute(':action, :forum<\\d+>, :?topic<\\d+>, :?page<\\d+>');

Ze vstupní URL si router si načte jen parametry, které jsou definované v routě. Můžeme mu klidně předávat $_SERVER['QUERY_STRING']. Pořadí vstupních parametrů není nijak závazné (na rozdíl od rout pro "pěkné URL"), ale výstupní parametry se vždy seřadí podle pořadí, v němž jsou definované v routě.

Skládání výstupních URL, doplňování dalších parametrů do query string nebo kotev, šablony či přesměrování - vše funguje stejně jako u pěkných URL. Jen pokud chcete v routách používat parametr route, je potřeba změnit nastavení routeru. Ve výchozím nastavení totiž předpokládá, že $_GET['route'] používá .htaccess pro "pěkné URL", takže tento parametr automaticky vyhazuje ze všech výstupních URL.

$router->setRouteKey('');

Můžete se podívat na testovací stránku pro SimpleRoute, jakým způsobem by pracoval s adresami typickými pro diskusní fórum

Kombinace Route a SimpleRoute

Ačkoli to vypadá trochu nesmyslně, je možné používat oba typy cest zároveň. Hodí se to např. v případě, že jste si nedávno změnili adresy na webu na "pěkné URL", ale ještě pořád k vám dost návštěvníků přichází i přes staré adresy z parametrů. Z jejich pohledu bude určitě lepší, když je dokážete poslat na novou adresu požadované stránky, než když je jen přesměrujete na úvod nebo chybovou stránku.

/** 
 * Podle ID stránky zjistí z DB její novou URL
 * (slouží jen jako příklad)
 */
function getPageUrl($params)    {
    // ... dotaz do DB ... vrací pole $row
    // najde url kategorie, případně i článku (pokud byl zadaný)
    $cil = array(
        'kategorie'   => $row['url_kategorie'],
        'controller'  => 'clanky',
    );
    if (!empty($row['url_clanku']))    {
        $cil['clanek'] = $row['url_clanku'];
    }
    return $cil;
}


$router = new Router;

// staré adresy, budou se přesměrovávat
$router[] = new SimpleRoute(':?id_clanku, :id_kategorie', array(), Route::REDIR, 'getPageUrl');

// podle této se poskládá cílová URL pro přesměrování.
$router[] = new Route('/:kategorie/:?clanek', array('controller' => 'clanky'));

// pokud to je adresa z parametrů a odpovídá první routě, přesměruje se
$router->parseUrl($_SERVER['QUERY_STRING']);

// pro všechny ostatní požadavky (pěkné URL)
$router->parseUrl($_GET['route']);

Nevýhodou je, že router v případě nenalezení odpovídající routy vyvolá varování (chybu E_USER_WARNING). To znamená u všech adres, kdy $_SERVER['QUERY_STRING'] není prázdné ale zároveň neodpovídá první routě. Na ostrém serveru ale většinou bývají chybové hlášky vypnuté nebo přesměrované do logu, takže tam by to nemělo moc vadit.

Poslední aktualizace: 24. 6. 2012 15:54