Das Zend Framework stellt verschiedene Alternativen zu den bereit gestellten Standardklassen zur Verfügung. Dies beinhaltet altive Request Objekte, Router und Response Objekte.
Zend_Controller_Request_Http
stellt ein Request Objekt für die
Verwendung in einer HTTP Umgebung bereit. Zend_Controller_Request_Http
ist die Standard Request Klasse, die von Zend_Controller_Dispatcher
verwendet wird.
Zend_Controller_Request_Http
kapselt den Zugriff auf relevante Werte
wie der Schlüssel und Wert für Controller und Action Variablen des Routers und alle
zusätzlichen Parameter, die aus der URI ermittelt wurden. Durch den Proxy zu
Zend_Controller_Request_Http
erlaubt es zusätzlich den Zugriff auf
superglobale Werte als öffentliche Eigenschaften und verwaltet die aktuelle Basis
URL und Request URI. Superglobale Werte können in einem Request Objekt nicht
gesetzt werden, stattdessen verwendet man die setParam/getParam Methoden um
Benutzerparameter zu setzen oder zu erhalten.
![]() |
Superglobale Daten |
---|---|
Beim Zugriff auf superglobale Daten über die öffentlichen Eigenschaften von
|
Auf spezifische superglobale Werte kann alternativ über eine öffentliche Methode
zugegriffen werden. Zum Beispiel kann auf den unverarbeitete Wert von
$_POST['user']
durch Aufruf der getPost('user')
Methode
des Request Objekts zugegriffen werden.
Zend_Controller_Request_Http
erlaubt, dass Zend_Controller_RewriteBase
in einem Unterverzeichnis verwendet werden kann. Zend_Controller_Request_Http
versucht, die Basis URL automatisch zu erkennen und entsprechend zu setzen.
Wenn man zum Beispiel seine index.php
in einem Webserverunterverzeichnis
mit Namen /projects/myapp/index.php
verwendet, sollte die Basis URL
(die Rewrite Basis) auf /projects/myapp
gesetzt werden. Dieser String
wird dann vom Anfang des Pfades entfernt, bevor irgend welche Routingtreffer
ermittelt werden. Dies befreit einem davon, es an den Anfang jeder Route setzen zu
müssen. Eine Route 'user/:username'
passt auf URIs wie
http://localhost/projects/myapp/user/martel
und
http://example.com/user/martel
.
![]() |
URL Erkennung beachtet Groß- und Kleinschreibung |
---|---|
Die automatische Erkennung der Basis URL beachtet die Groß- und Kleinschreibung, weshalb man sicherstellen sollte, dass die URL einem Unterverzeichnis im Dateisystem entspricht (sogar auf einem Windows Rechner). Andernfalls wird auf die noRoute aktion umgeleitet. |
Sollte die Basis URL falsch erkannt werden, kann man diese auch mit einem eigenen
Pfad mit Hilfe der setBaseUrl()
Methode der
Zend_Controller_Request_Http
Klasse oder der
Zend_Controller_Front
Klasse überschreiben. Die einfachste Methode ist
die von Zend_Controller_Front
, welche es an das Request Object weiter
leitet. Beispiel, um eine eigene Basis URL zu setzen:
/** * Dispatch Request with custom base URL with Zend_Controller_Front. */ $router = new Zend_Controller_RewriteRouter(); $controller = Zend_Controller_Front::getInstance(); $controller->setControllerDirectory('./application/controllers') ->setRouter($router) ->setBaseUrl('/projects/myapp'); // set the base url! $response = $controller->dispatch();
Zend_Controller_RewriteRouter
ist eine neue Version des Framework
Routers. Routing ist der Prozess der Übernahme und Zerteilung einer URI, um zu
ermitteln, welcher Controller und welche Aktion des Controllers die Anfrage
erhalten soll. Die Definition des Controllers, der Aktion sowie weiterer Parameter
wird in einem Objekt mit Namen Zend_Controller_Dispatcher_Token
gekapselt, das dann vom Zend_Controller_Dispatcher
verarbeitet wird.
Das Routing geschieht nur einmal: wenn zu Beginn die Anfrage erhalten wird und
bevor der erste Controller aufgerufen wird.
Zend_Controller_RewriteRouter
wurde entwickelt, um mit reinen PHP
Strukturen eine mod_rewrite ähnliche Funktionalität zu erlauben. Es richtet sich
sehr frei nach dem Ruby on Rails Routing und benötigt kein tieferes Wissen über
URL Weiterleitung des Webservers. Es wurde entwickelt, um mit einer einzigen
mod_rewrite Regel zu arbeiten.
RewriteEngine on RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php
oder:
RewriteEngine on RewriteCond %{SCRIPT_FILENAME} !-f RewriteCond %{SCRIPT_FILENAME} !-d RewriteRule ^(.*)$ index.php/$1
Der RewriteRouter kann auch mit dem IIS Webserver verwendet werden, wenn Isapi_Rewrite als Isapi Erweiterung installiert wurde und folgende Umschreibungsregel verwendet wird:
RewriteRule ^[\w/\%]*(?:\.(?!(?:js|ico|gif|jpg|png|css)$)[\w\%]*$)? /index.php [I]
![]() |
IIS Isapi_Rewrite |
---|---|
Bei Verwenung von IIS, wird |
Bei der verwendung von Lighttpd, ist folgende Umschreibungsregel gültig:
url.rewrite-once = ( ".*\.(js|ico|gif|jpg|png|css)$" => "$0", "" => "/index.php")
Um den RewriteRouter richtig zu verwenden, mußt du ihn instanziieren, einige benutzerdefinierte Routen hinzufügen und in den Controller einbinden. Der folgende Code veranschaulicht die Vorgehensweise:
/* Erstelle einen Router */ $router = new Zend_Controller_RewriteRouter(); $router->addRoute( 'user', new Zend_Controller_Router_Route('user/:username', array('controller' => 'user', 'action' => 'info')) ); /* binde ihn in den Controller ein */ $ctrl = Zend_Controller_Front::getInstance(); $ctrl->setRouter($router);
Das Herz des RewriteRouter ist die Definition der benutzerdefinierten Routen.
Routen werden durch Aufruf der addRoute
Methode des RewriteRouter
und der Übergabe einer neuen Instanz von Zend_Controller_Router_Route
erstellt:
$router->addRoute('user', new Zend_Controller_Router_Route('user/:username'));
Der erste Parameter ist der Name der Route. Zum derzeitigen Zeitpunkt ist er
redundant aber wird in Zukunft in einem URL View Helper verwendet, um eine einfache
Erstellung von URLs in deinen Views zu ermöglichen. Wenn du die vorher
konfigurierte, benannte Route verwenden möchtest, kannst du sie mit den
getRoute
Methode des RewriteRouter erhalten. Der zweite Parameter ist
eine Instanz von Zend_Controller_Router_Route
.
The erste Parameter für den Zend_Controller_Router_Route
Konstruktur
ist eine Route, die auf eine URL passt - zum Beispiel passt die obige Route
auf http://example.com/user/martel
. Der Doppelpunkt in einer Route
markiert eine URL Variable, die durch die
Zend_Controller_Action::_getParam
Methode zugänglich ist. In unserem
Beispiel wird der mit 'username' benannte Parameter auf den Wert 'martel' gesetzt.
![]() |
Reihenfolge der Definitionen |
---|---|
Routen werden in umgekehrter Reihenfolge abgeglichen, so dass man sicherstellen muss, dass die allgemeinste Route als erstes definiert ist. |
![]() |
Erlaubte Zeichen |
---|---|
Fürs Erste erlaubt die aktuelle Implementation die Verwendung jedes Zeichens für den Variablenbezeichner außer den Schrägstrich (/), es wird aber sehr empfohlen, dass du nur Zeichen verwendest, die für PHP Variablen verwendet werden dürfen. In Zukunft wird die Implementation vermutlich angepasst und dies könnte Fehler in deinen Code einführen. |
Es gibt zwei besondere Variablen, die in deinen Routen verwendet werden können - 'controller' und 'action'. Diese besonderen Variablen werden verwendet, um einen gewählten Controller und/oder eine Aktion in der URL zu finden. Die 'action' Variable muß immer entweder in der Route oder als Standardparameter definiert sein. Die 'controller' Variable wird standardmäßig auf IndexController verweisen, wenn sie nicht definiert wurde.
![]() |
Spezielle Variablen |
---|---|
Die Namen dieser speziellen Variablen können unterschiedlich sein, wenn man
die Standardwerte in |
$router->addRoute( 'user', new Zend_Controller_Router_Route(':controller/:action') );
Wenn du deinen Browser mit dieser Route auf http://example.com/news/latest
richtest, wird der Zend_Controller_Dispatcher
die Aktion latestAction
deines Controllers NewsController ausführen.
Jede Variable in der Route kann einen vorgegebenen Wert haben. Um diesen
vorzugeben, mußt du einen dritten Parameter zur addRoute
Methode
hinzufügen. Dieser dritte Parameter ist ein Array mit den Variablennamen als
Schlüssel und den vorgegebenen Werten als Werten.
$router->addRoute( 'archive', new Zend_Controller_Router_Route('archive/:year', array('year' => 2006)) );
Was nicht sofort erkennbar sein mag, ist, dass die obige Route auf URLs wie
http://example.com/archive/2005
und
http://example.com/archive
passt. Im letzteren Fall hat die Variable
'year' den Wert 2006.
Im obigen Beispiel haben wir keinen Controller angegeben, so dass immer auf die noRoute Aktion des IndexController verwiesen wird. Damit es anwendbar ist, musst du einen gültigen Controller und eine gültige Aktion als Standardwerte festlegen:
$router->addRoute( 'archive', new Zend_Controller_Router_Route('archive/:year', array('year' => 2006, 'controller' => 'archive', 'action' => 'show') );
This route will then result in dispatching to showAction of ArchiveController.
Du kannst einen dritten Parameter hinzufügen, in dem Anforderungen an die Variablen angegeben werden können. Diese werden als reguläre Ausdrücke definiert:
$router->addRoute( 'archive', new Zend_Controller_Router_Route('archive/:year', array('year' => 2006), array('year' => '\d+')) );
![]() |
Routing Verhalten |
---|---|
Im Gegensatz zu Ruby on Rails wird |
Im Gegensatz zum ursprünglichen Route kann RewriteRouter auch in Unterverzeichnissen verwendet werden. Die Methode setRewriteBase() des ursprünglichen RewriteRouter existiert nicht mehr. Stattdessen wird die Basis URL automatisch durch Zend_Controller_Request_Http ermittelt.
Sollte die Basis URL falsch erkannt werden, kannst du sie mit deinem eigenen Pfad mit Hilfe von Zend_Controller_Request_Http durch den Aufruf der setBaseUrl() Methode setzen (siehe Abschnitt 5.4.2.3, „Basis Url und Unterverzeichnisse“).
Zend_Controller_RewriteRouter
hat eine vordefinierte Standardroute, um
Kompatibilität mit der ersten Version des Routers zu gewährleisten. Sie
passt auf URIs in Form von 'controller/action'
and erkennt außerdem
jeden zusätzlichen Parameter, der an die URI angehängt wird. Sie ist wie folgt
konfiguiert:
// Route for Router v1 compatibility $compat = new Zend_Controller_Router_Route(':controller/:action/*', array('controller' => 'index', 'action' => 'index')); $this->addRoute('default', $compat);
![]() |
URIs abbilden |
---|---|
Zend_Controller_RewriteRouter wurde für Rückwärtskompatibilität konfiguriert.
Es passt automatisch auf |
Wenn man die Standardroute nicht in seinem Routing Schema haben möchte, kann diese
mit Hilfe von removeDefaultRoutes()
entfernt werden:
// Entferne Standardroute $router->removeDefaultRoutes();
Die obigen Beispiele verwenden alle dynamische Routen - Routen die zu prüfende Muster verwenden. Manchmal ist eine bestimmte Route jedoch fest verankert und die Verwendung regulärer Ausdrücke wäre zuviel des Guten. Die Antwort auf solche Situationen ist die Verwendung von statischen Routen:
$loginRoute = new Zend_Controller_Router_StaticRoute('login', array('controller' => 'login', 'action' => 'form')); $router->addRoute('login', $static);
Manchmal ist es praktischer, eine Konfigurationsdatei mit neuen Routen zu
aktualisieren, als den Code zu ändern. Dies ist mit Hilfe der
addConfig()
Methode möglich. Im Wesentlichen kann man eine
Zend_Config kompatible Konfiguration erstellen, in seinem Code einlesen und an den
RewriteRouter übergeben:
/** * Beispiel 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');
Im oberen Beispiel teilen wir dem Router mit, den 'routes' Bereich der INI Datei
für seine Routen zu verwenden. Jeder Schlüssel auf erster Ebene in diesem Bereich
wird verwendet, um den Namen der Routen zu definieren; das obige Beispiel definiert
die Routen 'archive' und 'news'. Jede Route erfordert dann mindestens einen 'route'
Eintrag und einen oder mehrere 'defaults' Einträge; optional können eine oder
mehrere 'reqs' (kurz für 'required', d.h. erforderlich) Einträge angegeben werden.
Alles in allem entspricht dies den drei Argumenten, die an ein
Zend_Controller_Router_Route_Interface
Objekt übergeben werden. Ein
Optionsschlüssel 'type' kann verwendet werden, um den Typ der Routenklasse für
diese Route anzugeben; standardmäßig wird Zend_Controller_Router_Route
verwendet. Im obigen Beispiel wird die 'news' Route definiert, um
Zend_Controller_Router_StaticRoute
zu verwenden.
Zend_Controller_Response_Http
ist ein Response Objekt, das für die
Verwendung in einer HTTP Umgebung geeignet ist. Es enthält Methoden für das Setzen,
Erhalten und Entfernen von Headern und die __toString()
Methode sendet
alle Header auf einmal bevor die Reponse Inhalte zurückgegeben werden.
setHeader()
nimmt zwei Argumente entgegen, einen Header Typ und den
Header Wert. Ein dritter, optionaler Parameter (wenn übergeben und true) erzwingt das
Überschreiben des vorhandenen Headers gleichen Typs mit dem neuen Header.