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_RewriteRouter 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_RewriteRouter(); $controller = Zend_Controller_Front::getInstance(); $controller->setControllerDirectory('./application/controllers') ->setRouter($router) ->setBaseUrl('/projects/myapp'); // ustaw bazowy URL! $response = $controller->dispatch();
Zend_Controller_RewriteRouter
jest nową wersją
routera 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. Routing ma
miejsce tylko raz: wtedy gdy żądanie jest po raz pierwszy
otrzymane, przed wywołaniem pierwszego kontrolera.
Zend_Controller_RewriteRouter
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
RewriteRouter 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ć RewriteRoutera musisz utworzyć jego instancję, zdefiniować jakieś trasy i przekazać ten obiekt do kontrolera. Poniższy kod pokazuje tą procedurę:
/* Utwórz router */ $router = new Zend_Controller_RewriteRouter(); $router->addRoute( 'user', new Zend_Controller_Router_Route('user/:username', array('controller' => 'user', 'action' => 'info')) ); /* Ustaw go w kontrolerze */ $ctrl = Zend_Controller_Front::getInstance(); $ctrl->setRouter($router);
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. |
W przeciwieństwie do oryginalnego routera, obecny RewriteRouter może być użyty w podkatalogach. Jednak oryginalna metoda RewriteRoutera setRewriteBase() nie jest już dostępna. Zamiast niej, 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 5.4.2.3, „Bazowy Url oraz podkatalogi”).
Zend_Controller_RewriteRouter jest skonfigurowany z jedną domyślną trasą w celu zapewnienia kompatybilności z pierwsza wersją routera. Dopasuje on adresy w zakresie kontrolera i akcji, a także domyślnie dopasuje dodatkowe parametry dołączone do adresu URI. Jest skonfigurowany w ten sposób:
// Trasa kompatybilna z pierwszą wersja routera $compat = new Zend_Controller_Router_Route(':controller/:action/*', array('controller' => 'index', 'action' => 'index')); $this->addRoute('default', $compat);
![]() |
Dopasowanie adresów URI |
---|---|
Zend_Controller_RewriteRouter jest skonfigurowany z kompatybilnością wsteczną. Automatycznie dopasuje kontroler i akcję z adresu wraz z dodatkowymi parametrami. Dodatkowe parametry nie wymagają dodawania nowych tras, o ile nie chcemy zdefiniować dla nich domyślnych wartości lub wymagań. Te dodatkowe parametry będą dostępne za pomocą metody Zend_Controller_Action::_getParam. |
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_StaticRoute('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_StaticRoute" * routes.news.route = "news" * routes.news.defaults.controller = "news" * routes.news.defaults.action = "list" */ $config = new Zend_Config_Ini($file); $router = new Zend_Controller_RewriteRouter(); $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_StaticRoute
.
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.