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/).