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.