Das Request-Objekt ist eine einfaches Werteobjekt, das zwischen
Zend_Controller_Front
und den Router, Dispatcher und Controller
Klassen übergeben wird. Es enthält sowohl die Definition des Controllers, der Aktion und
der Parameter, die an die Aktion übergeben werden sollen, als auch den Rest der
Anfrageumgebung, sei es HTTP, CLI oder
PHP-GTK.
-
Auf den Modulnamen kann über
getModuleName()
undsetModuleName()
zugegriffen werden. -
Auf den Controller-Namen kann über
getControllerName()
undsetControllerName()
zugegriffen werden. -
Auf den Namen der Aktion, die in diesem Controller aufgerufen wird, kann über
getActionName()
undsetActionName()
zugegriffen werden. -
Parameter, die von der Aktion ansprechbar sind, bestehen aus einem assoziativen Array mit Paaren von Schlüsseln und Werten, auf die komplett per
getParams()
undsetParams()
oder einzeln pergetParam()
undsetParam()
zugegriffen werden kann.
Abhängig vom Typ der Anfrage können auch weitere Methoden verfügbar sein. Das
verwendete Standard-Request-Objekt Zend_Controller_Request_Http
stellt z.B. Methoden zum Abfragen der Request-URI, Pfadinformationen,
den Parametern $_GET
und $_POST
usw. bereit.
Das Request-Objekt wird an den FrontController übergeben oder, wenn keines bereit gestellt wurde, am Anfang des Dispatcher-Prozesses instanziert, bevor das Routing beginnt. Es wird an jedes Objekt in der Dispatcherkette übergeben.
Zusätzlich ist das Request-Objekt besonders beim Testen sehr nützlich. Der Entwickler kann die Anfrageumgebung von Hand erstellen, inklusive Controller, Aktion, Parameter, URI usw. und das Request-Objekt an den Front Controller übergeben, um den Ablauf der Applikation zu testen. Zusammen mit dem Response-Objekt sind durchdachte und genaue UnitTests für eine MVC-Applikation möglich.
Zend_Controller_Request_Http
kapselt den Zugriff auf
relevante Werte wie Schlüsselname und Wert für Controller und Action, Variablen des
Routers und alle zusätzlichen Parameter, die aus der URI
ermittelt wurden. Es erlaubt 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
Methoden setParam()
und getParam()
um Benutzerparameter zu setzen oder zu erhalten.
Superglobale Daten
Beim Zugriff auf superglobale Daten über die öffentlichen Eigenschaften von
Zend_Controller_Request_Http
ist es notwendig, darauf zu
achten, dass der Eigenschaftsname (der superglobale Arrayschlüssel) einem
superglobalen Wert in einer bestimmten Reihenfolge entspricht: 1.
GET
, 2. POST
, 3.
COOKIE
, 4. SERVER
, 5.
ENV
.
Auf spezifische superglobale Werte kann alternativ über eine öffentliche Methode
zugegriffen werden. Zum Beispiel kann auf den unverarbeiteten Wert von
$_POST['user']
durch Aufruf der
Methode getPost('user')
des Request-Objekts zugegriffen
werden. Diese beinhalten getQuery()
, um
$_GET
-Elemente zu erhalten und
getHeader()
, um Request-Header zu erhalten.
GET- und POST-Daten
Es ist Vorsicht geboten, wenn auf Daten eines Anfrageobjekts zugegriffen wird, da diese in keiner Weise gefiltert werden. Der Router und Dispatcher prüfen und filtern Daten für die Verwendung innerhalb ihrer Aufgabe, lassen diese Daten aber unangetastet im Anfrageobjekt.
Abfrage der unverarbeitetet ("raw") POST-Daten
Ab 1.5.0 können auch die rohen POST-Daten über die
Methode getRawBody()
erhalten werden. Diese Methode
gibt FALSE
zurück, wenn keine Daten auf diesem Weg
übermittelt wurden, andernfalls den kompletten Inhalt von POST.
Das ist grundsätzlich sinnvoll, um Inhalt zu akzeptieren, wenn eine RESTvolle MVC-Anwendung entwickelt wird.
Im Anfrageobjekt können auch Benutzerparameter durch Verwendung von
setParam()
gesetzt werden und später durch
verwenden von getParam()
zurückgegeben werden. Der Router
verwendet diese Funktionalität, um passende Parameter in der
Anfrage-URI im Anfrageobjekt zu setzen.
getParam() empfängt mehr als Benutzerparameter
Um einfach seinen Job zu erledigen, sammelt getParam()
Daten von verschiedenen Quellen. Je nach Priorität enthalten diese:
Benutzerparameter, die über setParam()
gesetzt wurden,
GET
-Parameter und letztendlich
POST
-Parameter. Seien Sie sich dieser Tatsache bewusst,
wenn Sie Daten mit dieser Methode holen.
Wenn man nur Parameter erhalten will, die vorher mit
setParam()
gesetzt wurden, muß
getUserParam()
verwendet werden.
Zusätzlich kann seit 1.5.0 abgesichert werden, welche Parameterquellen durchsucht
werden. setParamSources()
erlaubt es, ein leeres Array
anzugeben oder ein Array mit einem oder mehreren Werten von '_GET' oder
'_POST' um zu zeigen, welche Parameterquellen erlaubt sind (standardmäßig sind
beide erlaubt); wenn der Zugriff nur auf '_GET' beschränkt werden soll, muß
setParamSources(array('_GET'))
angegeben werden.
Apache Quirks
Wenn der 404-Handler des Apache verwendet wird, um eingehende Anfragen an den
FrontController zu übergeben, oder ein PT Flag mit Rewrite Regeln verwendet wird,
enthält $_SERVER['REDIRECT_URL']
die URI,
die benötigt wird, nicht $_SERVER['REQUEST_URI']
. Wenn so ein
Setup verwendet wird und man ungültige Routen erhält, sollte man stattdessen die
Klasse Zend_Controller_Request_Apache404
statt der
Standard-HTTP-Klasse für das Anfrageobjekt verwenden:
$request = new Zend_Controller_Request_Apache404(); $front->setRequest($request);
Diese Klasse erweitert die Klasse
Zend_Controller_Request_Http
und modifiziert einfach die
automatische Erkennung der Anfrage-URI. Sie kann als
einfache Ersetzung verwendet werden.
Zend_Controller_Request_Http
erlaubt, dass
Zend_Controller_Router_Rewrite
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 irgendwelche Routingtreffer ermittelt werden.
Dies befreit einen davon, es am 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 eine Ausnahme geworfen.
Sollte die Basis-URL falsch erkannt werden, kann man diese auch
mit einem eigenen Pfad mit Hilfe der Methode setBaseUrl()
der Klasse Zend_Controller_Request_Http
oder der
Klasse Zend_Controller_Front
überschreiben. Die einfachste
Methode ist die von Zend_Controller_Front
, welche es an das
Request-Objekt weiterleitet. Nun Beispiel, um eine eigene
Basis-URL zu setzen:
/** * Dispatch-Anfrage mit einer kundenbasierenden URL mit Zend_Controller_Front. */ $router = new Zend_Controller_Router_Rewrite(); $controller = Zend_Controller_Front::getInstance(); $controller->setControllerDirectory('./application/controllers') ->setRouter($router) ->setBaseUrl('/projects/myapp'); // Setze die Basis-URL! $response = $controller->dispatch();
getMethod()
erlaubt es die
HTTP-Anfragemethode zu erkennen, die verwendet wurde, um die
aktuelle Ressource anzufragen.
Zusätzlich existiert eine Vielzahl von Methoden, die es erlauben, boolsche Antworten
zu erhalten, wenn gefragt wird, ob ein spezieller Typ von Anfrage durchgeführt wurde:
isGet()
isPost()
isPut()
isDelete()
isHead()
isOptions()
Der grundsätzliche Verwendungszweck hierfür ist die Erstellung von RESTvollen MVC-Architekturen.
Zend_Controller_Request_Http
hat eine rudimentäre Methode für
die Erkennung von AJAX-Anfragen:
isXmlHttpRequest()
. Diese Methode sucht nach einem
HTTP-Anfrageheader X-Requested-With mit dem
Wert 'XMLHttpRequest'; wenn er gefunden wird, gibt er TRUE
zurück.
Aktuell wird dieser Header standardmäßig mit den folgenden JS-Bibliotheken geschickt:
-
Prototype und Scriptaculous (und von Prototype abgeleitete Bibliotheken)
Yahoo! UI Library
jQuery
MochiKit
Die meisten AJAX-Bibliotheken erlauben das Senden von eigenen
HTTP-Anfrageheadern; wenn die eigene Bibliothek diesen Header
nicht sendet, muß dieser einfach zum Anfrageheader hinzugefügt werden um
sicherzustellen, dass die Methode isXmlHttpRequest()
funktioniert.
Die Basisanfrageklasse, die für alle Anfrageobjekte verwendet wird, ist die abstrakte
Klasse Zend_Controller_Request_Abstract
. Sie ist sehr
grundsätzlich und definiert die folgenden Methoden:
abstract class Zend_Controller_Request_Abstract { /** * @return string */ public function getControllerName(); /** * @param string $value * @return self */ public function setControllerName($value); /** * @return string */ public function getActionName(); /** * @param string $value * @return self */ public function setActionName($value); /** * @return string */ public function getControllerKey(); /** * @param string $key * @return self */ public function setControllerKey($key); /** * @return string */ public function getActionKey(); /** * @param string $key * @return self */ public function setActionKey($key); /** * @param string $key * @return mixed */ public function getParam($key); /** * @param string $key * @param mixed $value * @return self */ public function setParam($key, $value); /** * @return array */ public function getParams(); /** * @param array $array * @return self */ public function setParams(array $array); /** * @param boolean $flag * @return self */ public function setDispatched($flag = true); /** * @return boolean */ public function isDispatched(); }
Das Anfrageobjekt ist ein Behälter für die Anfrageumgebung. Die Controller-Kette muß wirklich nur wissen, wie der Controller, die Aktion, die optionalen Parameter und der Dispatched-Status gesetzt und empfangen werden können. Standardmäßig durchsucht das Anfrageobjekt die eigenen Parameter, indem es die Schlüssel für Controller oder Aktion verwendet um den Controller und die Aktion zu ermitteln.
Erweiteren Sie diese Klasse oder eine ihrer Derivate, wenn die Anfrageklasse mit einer speziellen Umgebung interagieren soll, um Daten für die obigen Aufgaben zu erhalten. Beispiele beinhalten die HTTP-Umgebung, eine CLI-Umgebung, oder eine PHP-GTK-Umgebung.