Mar 31 2008
Zend Framework: Routování subdomén
Routování v Zend Frameworku (ZF) není nic zvláště složitého. Stačí pouze lehce nahlédnout do dokumentance a začít používat defaultní routovaní případně si nastavit nějaká jiná vlastní pravidla.
Problém ale nastává v případě, že chcete do routování zahrnout subdomény. Na to ZF není přímo (zatím? — v době psaní tohoto článku je stable verze 1.5) vybaven a je tedy třeba použít kousek „vlastního kódu“.
Výchozí routovaní ZF
Předpokládejme že prezentace bude umístěna na domena.cz, výchozí routování v ZF je nastaveno takto:
domena.cz/controller/action/*
což odpovídá pravidlu
$route = new Zend_Controller_Router_Route(
'/:controller/:action/*',
array(
'controller' => 'index',
'action' => 'index'
)
);
Je tedy vidět, že pouze jednoduchou úpravou pravidel nelze subdomény zapojit do procesu routování.
Vlastní routovaní
Pojďme si tedy nejdříve popsat jednoduchý příklad struktury prezentace, na které budeme routování subdomén v ZF ukazovat. Mějme tedy doménu domena.cz. Na této doméně provozujeme například blog, který je rozdělen do několika kategorií, ty budou tvořit názvy subdomén. Jednotlivé příspěvky — články jsou pak zařazeny v těchto kategoriích (pro jednoduchost předpokládejme že jeden článek patří vždy jen do jedné kategorie). Jako základní subdoménu blogu si zvolíme www, na které budou umístěny základní informace, kontakty a podobné statické stránky. Struktura URL prezentace by tedy mohla vypadat nějak takto:
www.domena.cz/... - základní index, kontakty, ... <kategorie-url>.domena.cz/ - konkrétní kategorie blogu, zobrazuje seznam článků v dané kategorii <kategorie-url>.domena.cz/<clanek-url> - konkrétní článek konkrétní kategorie blogu
Pro toto řešení si vytvoříme dvě kolekce rout. První bude routovat základní subdoménu a její akce a druhá bude routovat kategorie a články. Předpokládejme že máme zajištěno že http://domena.cz se bude přesměrovávat na naši základní subdoménu http://www.domena.cz. Obě kolekce budou zapsány pro jednoduchost do bootstrap souboru (bootstrap.php).
Nejdříve je však třeba zjistit aktuální název subdomény, podle kterého se rozhodneme jakou kolekci použít.
Získání názvu domény a subdomény
// rozseknuti nazvu serveru
$domains = explode('.', $_SERVER["HTTP_HOST"]);
// aktualni subdomena
$subdomain = $domains[0];
Nyní si definujeme první kolekci rout pro základní index www.
První kolekce rout:
// zakladni www router
$www_router = new Zend_Controller_Router_Rewrite();
// zruseni defaultniho routovani
$www_router->removeDefaultRoutes();
// vlastni defaultni routa
$route = new Zend_Controller_Router_Route(
'/*',
array('controller' => 'index', 'action' => 'index')
);
$www_router->addRoute('default', $route);
// kontakt -- staticka stranka indexu
$route = new Zend_Controller_Router_Route(
'/contact/*',
array('controller' => 'index', 'action' => 'contact')
);
$www_router->addRoute('index_contact', $route);
// o nas -- staticka stranka indexu
$route = new Zend_Controller_Router_Route(
'/about/*',
array('controller' => 'index', 'action' => 'about')
);
$www_router->addRoute('index_about', $route);
Druhá kolekce rout pro subdoménové kategoriie:
// subdomenovy router -- kategorie
$sub_router = new Zend_Controller_Router_Rewrite();
$sub_router->removeDefaultRoutes();
// defaultni subdomenovy router
$route = new Zend_Controller_Router_Route(
'/*',
array(
'controller' => 'category',
'action' => 'index',
'category_url' => $subdomain,
)
);
$sub_router->addRoute('category_index', $route);
// konkretni clanek v kategorii
$route = new Zend_Controller_Router_Route(
'/:article_url/*',
array(
'controller' => 'article',
'action' => 'index',
'category_url' => $subdomain,
)
);
$sub_router->addRoute('article_index', $route);
A nakonec je třeba se rozhodnout, podle aktuální subdomény, kterou z kolekcí rout nastavíme jako primární a kterou jako alternativní. Pro uložení alternativní routy použijeme Zend_Registry.
Nastavení primární a alternativní kolekce rout
// rozhodnuti, ktera z rout je primarni dle subdomeny indexu
if ( 'www' === $subdomain )
{
$front->setRouter($www_router); // defaultni router -- index
Zend_Registry::set('alt_router', $sub_router); // alternativni router -- subdomeny
}
else
{
$front->setRouter($sub_router); // defaultni router -- subdomeny
Zend_Registry::set('alt_router', $www_router); // alternativni router -- index
}
Vlastní View a View-Helpery
Jelikož na odkazy, které budeme generovat do šablon, nelze přímo použít přibalený Zend_View_Helper_Url a musíme si tedy definovat vlastní URL helper a helpery pro generovaní indexových a subdoménových odkazů. Proto si hned v bootstrapu zavedeme i vlastni view do kterého si předáme parametry (doména a subdoména) již v bootstrapu a v helperech k ním budeme pouze přistupovat.
// vlastni view
$view = new Zend_View;
$view->setScriptPath(array('../application/views/scripts', '.'));
$view->setHelperPath('../application/views/helpers', 'Jens_View_Helper');
// ulozeni subdomeny a domeny do view
$view->server = new stdClass();
$view->server->subdomain = $subdomain;
$view->server->domain = $domains[1].'.'.$domains[2];
Zend_Registry::set('view', $view);
Pro generovaní URL si upravíme přiložený Zend_View_Helper_Url, nazveme si ho Jens_View_Helper_JensUrl. Ten bude fungovat tak, že v případě že neexistuje routa se jménem předaným argumentem $name, zkusíme z registru natáhnout a alternativní sadu rout a budeme hledat routu $name tam.
Dále si definujeme vlastní helpery pro generovaní odkazů základního indexu www: Jens_View_Helper_wwwUrl, pro generování odkazů na kategorie: Jens_View_Helper_CategoryUrl a pro generování odkazu na daný článék dané kategorie: Jens_View_Helper_ArticleUrl. Jednotlivé helpery zde nebudu dále popisovat, najdete je v přiloženém archivu ukázkové aplikace.
Ukázková aplikace
Součástí ukázkové aplikace jsou všechny výše popsané programové jednotky a další tři kontrolery a šablony pro zobrazování výstupu těchto kontrolerů. Celá aplikace má klasickou zendovskou strukturu:
domena.cz/
application/
controllers/
views/
helpers/
scripts/
library/
public/
Pro správné fungování musíte do adresáře library nahrát Zenda. V příkladu se používají subdomény www, php a zend, proto pokud používáte okna, musíte do host přidat něco takového:
127.0.0.1 www.domena.cz php.domena.cz zend.domena.cz
Samozřejmou nutností je správná konfigurace Apache pro virtuální doménu domena.cz a krásné URL s povoleným mod_rewrite:
ServerName www.domena.cz ServerAlias domena.cz *.domena.cz DocumentRoot /var/www/domena.cz/public <Directory /var/www/domena.cz/public/> Options FollowSymLinks AllowOverride All </Directory>
Aplikace ke stažení: příklad routování subdomén v Zend Frameworku
Použité verze aplikací:
Zend Framework 1.5 PHP Version 5.2.5-3 Apache/2.2.8 OS: Debian (Lenny) 2.6.22-3-686

22.04.2009, 08:37
Jen upozorňuji pro případné zájemce, že tento příklad routování už není v aktuálním Zend Frameworku (cca od verze 1.7) relevantní, neboť byla zavedena třída Zend_Controller_Router_Route_Hostname a ZF tedy už přímo podporuje routování domén a subdomén, více viz článek: Zend Framework: Hostname routing – routování domén a subdomén.