Der Standard RouterEinführungZend_Controller_Router_Rewrite ist der Standard Router des
Frameworks. Routing ist der Prozess der Übernahme und Zerteilung einer
URI (dem Teil der URI der nach der Basis
URL kommt), um zu ermitteln, welches Modul, welcher Controller und
welche Aktion des Controllers die Anfrage erhalten soll. Die Definition des Moduls, des
Controllers, der Aktion sowie weiterer Parameter wird in einem Objekt mit Namen
Zend_Controller_Dispatcher_Token gekapselt, das dann vom
Zend_Controller_Dispatcher_Standard verarbeitet wird. Das Routing
geschieht nur einmal: wenn zu Beginn die Anfrage erhalten wird und bevor der erste
Controller aufgerufen wird.
Zend_Controller_Router_Rewrite 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.
oder (bevorzugt):
Der Rewrite Router kann auch mit dem IIS Webserver verwendet werden
(Versionen <= 7.0), wenn Isapi_Rewrite als Isapi
Erweiterung installiert wurde und folgende Umschreibungsregel verwendet wird:
IIS Isapi_Rewrite
Bei Verwendung von IIS, wird
$_SERVER['REQUEST_URI'] entweder nicht vorhanden oder auf einen
leeren String gesetzt sein. In diesem Fall wird
Zend_Controller_Request_Http versuchen, den durch die
Isapi_Rewrite Erweiterung gesetzten Wert
$_SERVER['HTTP_X_REWRITE_URL'] zu verwenden.
IIS 7.0 führt ein natives URL Rewriting Modul
ein, und kann wie folgt konfiguriert werden:
]]>
Bei der Verwendung von Lighttpd, ist folgende Umschreibungsregel gültig:
"/index.php?$1",
".*\.(js|ico|gif|jpg|png|css|html)$" => "$0",
"" => "/index.php"
)
]]>Einen Router verwenden
Um den Rewrite Router richtig zu verwenden, muß er instanziiert, einige
benutzerdefinierte Routen hinzufügt und in den Controller einbunden werden. Der folgende
Code veranschaulicht die Vorgehensweise:
getRouter(); // gibt standardmäßig einen Rewrite Router zurück
$router->addRoute(
'user',
new Zend_Controller_Router_Route('user/:username',
array('controller' => 'user',
'action' => 'info'))
);
]]>Grundsätzliche Rewrite Router Operationen
Das Herz des RewriteRouters ist die Definition von Benutzerdefinierten Routen. Routen
werden durch aufruf der addRoute Methode des RewriteRouters hinzugefügt und übergeben
eine neue Instanz einer Klasse die
Zend_Controller_Router_Route_Interface implementiert. Z.B.:
addRoute('user',
new Zend_Controller_Router_Route('user/:username'));
]]>
Der Rewrite Router kommt mit sechs Basistypen von Routen (eine von denen ist speziell):
is special):
Zend_Controller_Router_Route
Zend_Controller_Router_Route_Static
Zend_Controller_Router_Route_Regex
Zend_Controller_Router_Route_Hostname
Zend_Controller_Router_Route_Chain
Zend_Controller_Router_Rewrite
*
Routen können unzählige Male verwendet werden um eine Kette oder benutzerdefinierte
Routing Schemas von Anwendungen zu erstellen. Es kann jede beliebige Anzahl von Routen
in jeder beliebigen Konfiguration verwendet werden, mit Ausnahme der Modul Route, welche
nur einmal verwendet werden sollte, und möglicherweise die am meisten standardmäßige
Route ist (z.B., als ein Standard). Jede Route wird später detailiert beschrieben.
Der erste Parameter für addRoute ist der Name der Route. Er wird als Handle verwendet um
die Route außerhalb des Routers zu erhalten (z.B. für den Zweck der
URL Erzeugung). Der zweite Parameter ist die Route selbst.
Die gewöhnlichste Verwendung des Namens der Route ist gegeben durch die Zwecke des
Zend_View Url Helfers:
url(array('username' => 'martel'), 'user') ?>">Martel
]]>
Was zu folgender href führt: user/martel.
Routen ist ein einfacher Prozess des Durchlaufens aller vorhandenen Routen und
Vergleichens deren Definitionen mit der aktuellen Anfrage URI. Wenn
ein positiver Vergleich gefunden wird, werden variable Werte von der Instanz des Routers
zurückgegeben, und werden für die spätere Verwendung im Dispatcher in das
Zend_Controller_Request Objekt iniziiert, sowie in von Benutzern
erstellten Controllern. Bei einem negativen Ergebnis des Vergleiches, wird die nächste
Route in der Kette geprüft.
Wenn man herausfinden will welche Route gepasst hat, kann man die
getCurrentRouteName() Methode verwenden, die den Identifikator
zurückgibt der verwendet wurde als die Route im Router registriert wurde. Wenn man das
aktuelle Route Objekt benötigt, kann getCurrentRoute()
verwendet werden.
Umgekehrter Vergleich
Routen werden in umgekehrter Reihenfolge verglichen. Deswegen muß sichergestellt
werden das die generellen Routen zuerst definiert werden.
Zurückgegebene Werte
Werte die vom Routen zurückgegeben werden kommen von URL
Parametern oder Benutzerdefinierten Router Standards. Diese Variablen sind später
durch die Zend_Controller_Request::getParam() oder
Zend_Controller_Action::_getParam()Methoden verwendbar.
Es gibt drei spezielle Variablen welche in den Routen verwendet werden können -
'module', 'controller' und 'action'. Diese speziellen Variablen werden durch
Zend_Controller_Dispatcher verwendet um einen Controller und die
Aktion zu funden zu der verwiesen wird.
Spezielle Variablen
Die Namen dieser speziellen Variablen kann unterschiedlich sein wenn entschieden
wird die Standards in Zend_Controller_Request_Http mithilfe
der setControllerKey() und
setActionKey() Methode zu Ändern.
Standard RoutenZend_Controller_Router_Rewrite kommt mit einer Standard Route
vorkonfiguriert, welche URIs im Sinn von
controller/action entspricht. Zusätzlich kann ein Modul Name als
erstes Pfad Element definiert werden, welches URIs in der Form von
module/controller/action erlaubt. Letztendlich wird es auch allen
zusätzlichen Parametern entsprechen die der URI standardmäßig
hinzugefügt wurden - controller/action/var1/value1/var2/value2.
Einige Beispiele wie solche Routen verglichen werden:
setControllerDirectory(
array(
'default' => '/path/to/default/controllers',
'news' => '/path/to/news/controllers',
'blog' => '/path/to/blog/controllers'
)
);
Nur Modul:
http://example/news
module == news
Ungültiges Modul, geht an den Controller Namen:
http://example/foo
controller == foo
Modul + Controller:
http://example/blog/archive
module == blog
controller == archive
Modul + Controller + Aktion:
http://example/blog/archive/list
module == blog
controller == archive
action == list
Modul + Controller + Aktion + Parameter:
http://example/blog/archive/list/sort/alpha/date/desc
module == blog
controller == archive
action == list
sort == alpha
date == desc
]]>
Die Standardroute ist einfach ein
Zend_Controller_Router_Route_Module Objekt welches unter dem
Namen (Index) 'default' im RewriteRouter gespeichert ist. Es wird mehr oder weniger wie
folgt erstellt:
addRoute('default', $compat);
]]>
Wenn diese spezielle Standard Route im eigenen Routing Schema nicht gewünscht ist, kann
Sie durch Erstellung einer eigenen 'default' Route überschrieben werden (z.B. durch
Speichern unter dem Namen 'default') oder dem kompletten Entfernen durch verwenden von
removeDefaultRoutes():
removeDefaultRoutes();
]]>Basis URL und Unterverzeichnisse
Der Rewrite Router kann in Unterverzeichnissen verwendet werden (z.B.
http://domain.com/user/application-root/) und in diesem Fall
sollte die Basis URL der Anwendung
(/user/application-root) automatisch durch
Zend_Controller_Request_Http erkannt und auch verwendet werden.
Sollte die Basis URL nicht richtig erkannt werden kann diese mit
eigenen Basispfad überschrieben werden durch Verwendung von
Zend_Controller_Request_Http und Auruf der
setBaseUrl() Methode (siehe Basis URL und
Unterverzeichnisse):
setBaseUrl('/~user/application-root/');
]]>Globale Parameter
Man kann in einem Router globale Parameter setzen die der Route automatisch zur
Verfügung stehen wenn Sie durch setGlobalParam() eingefügt
werden. Wenn ein globaler Parameter gesetzt ist, aber auch direkt an die Assemble
Methode gegeben wird, überschreibt der Benutzer-Parameter den Globalen-Parameter.
Globale Parameter können auf folgendem Weg gesetzt werden:
setGlobalParam('lang', 'en');
]]>Router TypenZend_Config mit dem RewriteRouter verwenden
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:
Als Beispiel wird die folgende INI Datei angenommen:
Die oben angeführte INI Datei kann dann wie folgt in ein
Zend_Config Objekt eingelesen werden:
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_Route_Static zu verwenden.
Erben vom Router
Der Standard Rewrite Router sollte die meisten Funktionalitäten die benötigt werden zur
Verfügung stellen; meistens wird es nur notwendig sein einen neuen Router Typen zu
erstellen um neue oder modifizierte Funktionalitäten für die verfügbaren Routen zu
bieten.
So gesehen, wird man in einigen Fällen ein anderes Routing Paradigma verwenden wollen.
Das Interface Zend_Controller_Router_Interface bietet die
minimalen Information die benötigt werden um einen Router er erstellen und besteht aus
einer einzigen Methode.
Das Routing findet nur einmal statt, wenn die Anfrage das erste Mal vom System erhalten
wird. Der Zweck des Routers ist es, Controller, Aktion und optionale Parameter auf Basis
der Anfrageumgebung zu ermitteln und im Request zu setzen. Das Request Objekt wird dann
an den Dispatcher übergeben. Wenn es nicht möglich ist, eine Route auf einen Dispatch
Token abzubilden, soll der Router nichts mit dem Request Objekt machen.