Routery Part w Zend Framework 2 i sprawdzanie nazwy domeny
Zend Framework 2 jest już w wersji beta 3 i wielkimi krokami zbliża się faza RC i w końcu oficjalny release. Mam okazję pracować w tym frameworku przy kilku projektach i poznawać mniejsze i większe nowości, które nowe wydanie oferuje programistom. Jedną z tych mniejszych, ale bardzo ciekawych zmian jest wprowadzenie nowego typu routera adresów URL – Part.
Routery w aplikacjach webowych, to mechanizmy odwzorowujące adres żądania klienta (czyli adres wprowadzony do przeglądarki WWW) na odpowiednie zasoby systemu (w przypadku aplikacji MVC w ZF są to kontrolery akcji). Router typu Part umożliwia tworzenia zagnieżdżonych grup routingu, dzięki czemu można sprawdzać fragmenty adresów. Dokumentacja oficjalna pokazuje jak można testować część adresową URL, żeby w każdym przypadku nie duplikować początkowych fragmentów adresów. Jeszcze ciekawsze rzeczy można osiągnąć łącząc ten router z routerem domenowym.
Wyobraźmy sobie, że mamy aplikację, która ma osobny frontend dla odwiedzających użytkowników i backend do zarządzania treścią oraz obie te części znajdują się w różnych domenach (np. www.example.com i admin.example.com). Żeby móc konfigurować osobno kontrolery dla front- i backendu możmy skorzystać właśnie z kombinacji routerów part, hostname i pozostałych, bardziej standardowych. Dodatkowo, aby w jeden router połączyć niezależne ścieżki możemy skorzystać z RouteStacka – specjalnej klasy, która działa podobnie jak router, ale nie ma żadnych własnych reguł tylko sprawdza kolejne niezależne routery. Dzięki temu nie musimy tworzyć wspólnego początku ściężki i już na poziomie domeny możemy mieć zupełnie różne adresy.
W kodzie poniżej zostaną użyte następujące klasy:
use ZendMvcRouterHttpPart, // router fragmentów adresów ZendMvcRouterRouteBroker, // umożliwia automatyczne tworzenie obiektów na podstawie nazw klas ZendMvcRouterHttpTreeRouteStack; // umożliwia zagnieżdżanie wielu routerów
Aby skonfigurować obiekt RouteStack kolejno tworzymy routing dla frontendu:
$routeFrontend = Part::factory(array( 'route' => array( 'type' => 'Zend\Mvc\Router\Http\Hostname', 'options' => array( 'route' => 'www.example.com', ), ), 'route_broker' => new RouteBroker, 'child_routes' => array( 'home' => array( 'type' => 'Zend\Mvc\Router\Http\Literal', 'options' => array( 'route' => '/', 'defaults' => array( 'controller' => 'Frontend\Controller\HomeController', 'action' => 'index', ), ), ), ), ));
routing dla backendu:
$routeBackend = Part::factory(array( 'route' => array( 'type' => 'Zend\Mvc\Router\Http\Hostname', 'options' => array( 'route' => 'admin.example.com', ), ), 'route_broker' => new RouteBroker, 'child_routes' => array( 'dashboard' => array( 'type' => 'Zend\Mvc\Router\Http\Literal', 'options' => array( 'route' => '/', 'defaults' => array( 'controller' => 'Backend\Controller\DashboardController', 'action' => 'index', ), ), ), ), ));
i RouteStack:
$route = TreeRouteStack::factory(array( 'route_broker' => new RouteBroker, 'routes' => array( 'frontend' => $routeFrontend, 'backend' => $routeBackend, ), ));
Pozstałe części adresów (np. www.example.com/products) konfirugujemy wg schematu z wyżej wspomnianej dokumentacji.
Po wykonaniu $route->match($request);
dostaniemy obiekt RouteMatch, który jako nazwę pasującej ścieżki będzie zawierał kolejne nazwy oddzielone znakiem /, czyli w powyższym przykładzie frontend/home lub backend/dashboard. Analogicznie w drugą stronę tworzyć adresy możemy przez $route->assemble(array(), array('name' => 'backend/dashboard'));
gdzie w rezultacie otrzymamy pełny adres URI z protokołem i domeną (w przykładzie http://admin.example.com/).