Zend Framework zapewnia kilka alternatyw dla domyślnych klas, włączając w to alternatywne obiekty żądania, routery oraz obiekty odpowiedzi.
Zend_Controller_Request_Http zapewnia obiekt
żądania do użycia w środowisku HTTP. Klasa
Zend_Controller_Request_Http jest domyślną klasą
żądania używaną przez Zend_Controller_Dispatcher.
Zend_Controller_Request_Http obudowuje dostęp
do odpowiednich wartości takich jak nazwa klucza i wartość
dla zmiennych kontrolera i akcji routera, oraz do dodatkowych
parametrów pobranych z adresu URI. Rozszerzając
Zend_Controller_Request_Http dodatkowo pozwala na
uzyskanie dostępu do wartości zawartych w superglobalnych
tablicach jako do publicznych właściwości obiektu i zarządza
obecnym bazowym adresem URL oraz adresem URL żądania.
Superglobalne wartości nie mogą być ustawione w obiekcie
żądania, zamiast tego użyj metod setParam/getParam aby ustawić
lub odebrać parametry użytkownika.
![]() |
Dane superglobalne |
|---|---|
Kiedy uzyskujemy dostęp do danych superglobalnych za pomocą
klasy |
Konkretne zmienne superglobalne mogą być alternatywnie dostępne
za pomocą publicznej metody. Na przykład, wartość
$_POST['user'] może być dostępna przez wywołanie
metody getPost('user') na obiekcie żądania.
Klasa Zend_Controller_Request_Http pozwala na użycie
klasy Zend_Controller_Router_Rewrite w podkatalogach.
Zend_Controller_Request_Http spróbuje automatycznie wykryć twój
bazowy adres URL i ustawi go odpowiednio.
Na przykład jeśli twój plik index.php jest w
podkatalogu nazwanym /projects/myapp/index.php,
bazowy URL (bazowy adres przepisania) powinien być ustawiony na
/projects/myapp. Ten łańcuch znaków zostanie
obcięty z początu ścieżki zanim będą dopasowane jakiekolwiek trasy.
To zwalnia z konieczności dołączania tego adresu do każdej z tras.
Trasa 'user/:username' dopasuje adresy URI takie
jak http://localhost/projects/myapp/user/martel oraz
http://example.com/user/martel.
![]() |
Detekcja URL jest wrażliwa na małe i duże litery |
|---|---|
Automatyczna detekcja adresów URL jest wrażliwa na małe i duże litery, więc upewnij się, że adres URL zostanie dobrze dopasowany do nazwy podkatalogu w systemie plików (nawet w systemie Windows). Jeśli nie zostanie, zostanie wywołana akcja noRoute. |
Jeśli bazowy adres URL jest wykrywany nieprawidłowo, możesz
go nadpisać w obiekcie Zend_Http_Request wywołując metodę
setBaseUrl() lub tą samą metodę klasy
Zend_Controller_Request_Http lub klasy
Zend_Controller_Front. Najłatwiejszy sposób
to ustawienie tego w klasie Zend_Controller_Front,
która przekaże to do obiektu żądania. Przykładowe użycie
ustawiania własnego bazowego adresu URL:
/**
* Uruchom żądanie z własnym bazowym URL za pomocą Zend_Controller_Front.
*/
$router = new Zend_Controller_Router_Rewrite();
$controller = Zend_Controller_Front::getInstance();
$controller->setControllerDirectory('./application/controllers')
->setRouter($router)
->setBaseUrl('/projects/myapp'); // ustaw bazowy URL!
$response = $controller->dispatch();
Zend_Controller_Router_Rewrite jest standardowym
routerem we frameworku. Routing jest procesem pobrania adresu
URI i rozłożenia go w celu ustalenia jaki kontroler i jaka akcja
powinny otrzymać żądanie. Ta informacja o kontrolerze, akcji i
opcjonalnych parametrach jest pakowana do obiektu
Zend_Controller_Request_Http, który jest potem
przetwarzany przez Zend_Controller_Dispatcher_Standard.
Routing ma miejsce tylko raz: wtedy gdy żądanie jest po raz
pierwszy otrzymane, przed wywołaniem pierwszego kontrolera.
Zend_Controller_Router_Rewrite jest zaprojektowany w
celu uzyskania w czystym PHP takiej funkcjonalności jak w
mod_rewrite. Jest to luźno wzorowane na routingu Ruby on Rails i
nie wymaga żadnej wiedzy o przepisywaniu adresów przez serwer
www. Jest to zaprojektowane w taki sposób, aby działało po
dodaniu tylko jednej reguły mod_rewrite (jednej z poniższych):
RewriteEngine on RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php
lub:
RewriteEngine on
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1
Rewrite router może być także użyty z serwerem IIS, jeśli moduł Isapi_Rewrite jest zainstalowany jako rozszerzenie Isapi, z taką regułą przepisywania:
RewriteRule ^[\w/\%]*(?:\.(?!(?:js|ico|gif|jpg|png|css)$)[\w\%]*$)? /index.php [I]
![]() |
IIS Isapi_Rewrite |
|---|---|
Jeśli używasz serwera IIS, to wartość
|
Jeśli używasz serwera Lighttpd, poniższa reguła jest prawidłowa:
url.rewrite-once = ( ".*\.(js|ico|gif|jpg|png|css)$" => "$0", "" => "/index.php")
Aby prawidłowo użyć rewrite routera musisz utworzyć jego instancję, zdefiniować jakieś trasy i przekazać ten obiekt do kontrolera. Poniższy kod pokazuje tą procedurę:
/* Utwórz router */
$router = $ctrl->getRouter(); // domyślnie zwraca rewrite router
$router->addRoute(
'user',
new Zend_Controller_Router_Route('user/:username', array('controller' => 'user', 'action' => 'info'))
);
Sercem RewriteRoutera jest definicja tras określonych przez
użytkownika. Trasy są tworzone przez wywołanie metody addRoute
obiektu RewriteRouter i przekazanie do niej nowej instancji
obiektu Zend_Controller_Router_Route:
$router->addRoute('user', new Zend_Controller_Router_Route('user/:username'));
Pierwszy parametr jest nazwą trasy. Obecnie nie jest konieczne
jego definiowanie, jednak będzie on używany w przyszłości w
klasie pomocniczej widoku ułatwiającej łatwe generowanie adresów
URL. Jeśli chcesz użyć wcześniej skonfigurowanej trasy, możesz
ją odebrać za pomocą metody getRoute RewriteRoutera. Drugi
parametr jest instancją Zend_Controller_Router_Route.
Pierwszy parametr konstruktora obiektu
Zend_Controller_Router_Route jest trasą, która ma
być dopasowana do adresu URL - na przykład powyższa trasa
zostanie dopasowana do adresu http://example.com/user/martel.
Dwukropek w trasie oznacza zmienną adresu URL. Po udanym dopasowaniu
trasy, wartości wszystkich zdefiniowanych zmiennych zostaną przekazane
do obiektu Zend_Controller_Request. Po tym będą one dostępne za pomocą
metod Zend_Controller_Request::getParam oraz
Zend_Controller_Action::_getParam. W naszym przykładzie
parametr nazwany username będzie miał ustawioną wartość 'martel'.
![]() |
Odwrotne dopasowywanie |
|---|---|
Trasy są dopasowywane w odwrotnej kolejności więc musisz pamiętać żeby podstawowe trasy były zdefiniowane na początku. |
![]() |
Użycie znaków |
|---|---|
Teraz obecna implementacja pozwala na użycie w nazwie zmiennej dowolnych znaków z wyjątkiem ukośnika (/), ale jest mocno zalecane używanie jedynie znaków, które są bezproblemowo obsługiwane ptzrz PHP. W przyszłości implementacja prawdopodobnie zostanie zmodyfikowana co mogłoby wprowadzić do twojego kodu błędy. |
Są dwie specjalne zmienne które nie mogą być użyte w twoich trasach - ':controller' oraz ':action'. Te specjalne zmienne będą użyte aby znaleść kotroler oraz akcję w danym adresie URL. Zmienna ':action' zawsze musi być zdefiniowana w trasie lub jako domyślny parametr. Zmienna ':controller' będzie domyślnie ustawiona na IndexController jeśli nie będzie zdefiniowana.
![]() |
Specjalne zmienne |
|---|---|
Nazwy tych specjalnych zmiennych mogą być inne, jeśli zdecydujesz
zmienić je w obiekcie |
$router->addRoute(
'user', new Zend_Controller_Router_Route(':controller/:action')
);
Jeśli skierujesz przeglądarkę na adres
'http://example.com/news/latest' ze zdefiniowaną powyższą trasą
Zend_Controller_Dispatcher odwoła się do akcji
latestAction z kontrolera NewsController.
Każda zmienna w trasie może mieć wartość domyślną. Aby to
zrobić, musisz przekazać drugi parametr do konstruktora
Zend_Controller_Router_Route. Ten parametr jest
tablicą z nazwami zmiennych jako kluczami i z wartościami,
które mają być uznane za domyślne.
$router->addRoute(
'archive', new Zend_Controller_Router_Route('archive/:year', array('year' => 2006))
);
Może nie jest wyraźnie widoczne to, że powyższa trasa dopasuje adresy URL takie jak 'http://example.com/archive/2005' oraz 'http://example.com/archive'. Ostatecznie zmienna year i tak będzie miała wartość 2006.
Powyższy przykład spowoduje jedynie przekazanie zmiennej oznaczającej rok do żądania. Nie będzie miał miejsca routing, ponieważ parametry oznaczające kontroler i akcję nie są ustawione. Aby było to bardziej użyteczne, musisz zapewnić prawidłową nazwę kontrolera i akcji jako domyślne wartości.
$router->addRoute(
'archive',
new Zend_Controller_Router_Route('archive/:year', array('year' => 2006, 'controller' => 'archive', 'action' => 'show')
);
Ta trasa spowoduje uruchomienie akcji showAction kontrolera ArchiveController.
Można dodać trzeci parametr do konstruktora
Zend_Controller_Router_Route w którym będą
ustawione wymagania zmiennych. Są one zdefiniowane jako
wyrażenia regularne:
$router->addRoute(
'archive',
new Zend_Controller_Router_Route('archive/:year', array('year' => 2006), array('year' => '\d+'))
);
![]() |
Zachowanie routera |
|---|---|
W przeciwieństwie do Ruby on Rails, RewriteRouter z ZF dopasuje trasę i użyje domyślnej gdy trzeci parametr zawierający wymagania zmiennych nie zostanie znaleziony. Więc adres URL 'http://example.com/archive/test' zostanie dopasowany do powyższej trasy, a rok zostanie ustawiony na 2006. Ta funkcjonalność może w przyszłości się zmienić, ponieważ w momencie pisania tej dokumentacji ta kwestia jest jeszcze uzgadniana. |
Rewrite router może być użyty w podkatalogach, a bazowy adres
URL zostanie automatycznie wykryty przez obiekt
Zend_Controller_Request_Http.
Jeśli bazowy adres URL jest wykrywany nieprawidłowo, możesz
go nadpisać w obiekcie Zend_Controller_Request_Http
wywołując metodę setBaseUrl() (zobacz
Sekcja 7.4.2.3, „Bazowy Url oraz podkatalogi”).
Zend_Controller_Router_Rewrite jest skonfigurowany z jedną domyślną
trasą. Dopasuje on adresy w postaci 'controller/action' .
Dodatkowo, nazwa modułu może być określoa jako pierwszy element
ścieżki, pozwalając na użycie adresów w postaci
'module/controller/action. Ostatecznie domyślnie
dopasuje dodatkowe parametry dołączone do adresu URI.
Kilka przykładów doopasowania tras:
// Zakładając poniższe:
// $ctrl->setControllerDirectory(array(
// 'default' => '/path/to/default/controllers',
// 'news' => '/path/to/blog/controllers',
// 'blog' => '/path/to/blog/controllers'
// ));
Tylko moduł:
http://example/news
module == news
Nieprawidłowy moduł mapuje do nazwy kontrolera:
http://example/foo
controller == foo
Moduł oraz kontroler:
http://example/blog/archive
module == blog
controller == archive
Moduł, kontroler oraz akcja:
http://example/blog/archive/list
module == blog
controller == archive
action == list
Moduł, kontroler, akcja oraz parametry:
http://example/blog/archive/list/sort/alpha/date/desc
module == blog
controller == archive
action == list
sort == alpha
date == desc
Domyślną trasą jest obiekt
Zend_Controller_Router_Route_Module utworzony
bez żadnych domyślnych parametrów:
// Trasa kompatybilna z pierwszą wersja routera
$compat = new Zend_Controller_Router_Route_Module();
$this->addRoute('default', $compat);
![]() |
Dopasowanie adresów URI |
|---|---|
|
Jeśli nie potrzebujesz domyślnych tras w swoim schemacie
routingu, możesz je usunąć używając metody removeDefaultRoutes():
// Usuwa domyślną trasę $router->removeDefaultRoutes();
Wszystkie powyższe przykłady używają dynamicznych tras -- tras, które są dopasowywane do szablonów. Czasem jakaś trasa jest niezmienna, a ciągłe sprawdzanie wyrażenia regularnego może być zabójcze dla serwera. Rozwiązaniem takiej sytuacji jest użycie statycznych tras:
$loginRoute = new Zend_Controller_Router_Route_Static('login', array('controller' => 'login', 'action' => 'form'));
$router->addRoute('login', $static);
Czasem wygodniej jest uaktualnić plik konfiguracyjny z nowymi
trasami niż zmieniać kod. Jest to możliwe za pomocą metody
addConfig(). Zasadniczo tworzysz konfigurację
kompatybilną z Zend_Config, a w kodzie odczytujesz ją i
przekazujesz ją do RewriteRoutera.
/** * Przykładowy plik INI: * routes.archive.route = "archive/:year/*" * routes.archive.defaults.controller = archive * routes.archive.defaults.action = show * routes.archive.defaults.year = 2000 * routes.archive.reqs.year = "\d+" * * routes.news.type = "Zend_Controller_Router_Route_Static" * routes.news.route = "news" * routes.news.defaults.controller = "news" * routes.news.defaults.action = "list" */ $config = new Zend_Config_Ini($file); $router = new Zend_Controller_Router_Rewrite(); $router->addConfig($config, 'routes');
W powyższym przykładzie, nakazujemy routerowi użyć sekcji 'routes'
pliku INI aby użyć tras zdefiniowanych w tym pliku. Każdy element
pierwszego poziomu w tej sekcji będzie użyty do zdefiiniowania
nazwy trasy; powyższy przekład definiuje trasy 'archive' oraz
'news'. Wymagane jest aby każda trasa miała określony przynajmniej
parametr 'route' i jeden lub więcej parametrów 'defaults';
opcjonalnie mogą być zdeiniowane parametry 'reqs' (skrót
'required'). Wszystkie te parametry odpowiadają trzem argumentom
przekazywanym do obiektu Zend_Controller_Router_Route_Interface
Klucz opcji 'type' może być użyty aby określić typ
klasy, która ma być użyta dla danej trasy; domyślnie używana jest
klasa Zend_Controller_Router_Route. W powyższym
przykładzie, trasa 'news' jest zdefiniowana aby używała
Zend_Controller_Router_Route_Static.
Zend_Controller_Response_Http jest obiektem odpowiedzi
odpowiednim do użycia w środowisku HTTP. Zawiera metody
do ustawiania, odbierania i czyszczenia nagłówków, a metoda
__toString() wysyła wszystkie nagłówki na raz przed
wysłaniem zawartości odpowiedzi.
Metoda setHeader() przyjmuje dwa argumenty, typ nagłówka
oraz wartość nagłówka. Trzeci opcjonalny parametr, jeśli jest
przekazany i ma wartość true, spowoduje, że nowy nagłówek zastąpi
inne zarejestrowane nagłówki o tym typie.