7.4. Das Request Objekt

7.4.1. Einführung

Das Request Objekt ist eine einfaches Wertobjekt, 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, seit es HTTP, CLI oder PHP-GTK.

  • Auf den Modul Namen kann über getModuleName() und setModuleName() zugegriffen werden.

  • Auf den Controller Namen kann über getControllerName() und setControllerName() zugegriffen werden.

  • Auf den Namen der Aktion, die in diesem Controller aufgerufen wird, kann über accessed by getActionName() und setActionName() zugegriffen werden.

  • Parameter, die von der Aktion ansprechbar sind, bestehen aus einem assoziativen Array mit Schlüssel/Wert Paaren, auf die komplett per getParams() und setParams() oder einzeln per getParam() und setParam() zugegriffen werden kann.

Abhängig vom Typ der Anfrage können auch weitere Methoden verfügbar sein. Das verwendete Standard Request Object Zend_Controller_Request_Http stellt z.B. Methoden zum Abfragen der Request URI, Pfadinformationen, $_GET und $_POST Parameter usw. bereit.

Das Request Objekt wird an den Front Controller ü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 Object 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 übrgeben, um den Ablauf der Applikation zu testen. Zusammen mit dem Response Objekt sind durchdachte und genaue Unit Tests für eine MVC Applikation möglich.

7.4.2. HTTP Anfragen

7.4.2.1. Auf Request Daten zugreifen

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. 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 setParam/getParam Methoden um Benutzerparameter zu setzen oder zu erhalten.

[Anmerkung] 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 unverarbeitete Wert von $_POST['user'] durch Aufruf der getPost('user') Methode des Request Objekts zugegriffen werden. Diese beinhalten getQuery(), um $_GET Elemente zu erhalten und getHeader(), um Request Header zu erhalten.

[Anmerkung] GET and POST data

Be cautious when accessing data from the request object as it is not filtered in any way. The router and dispatcher validate and filter data for use with their tasks, but leave the data untouched in the request object.

You may also set user parameters in the request object using setParam() and retrieve these later using getParam(). The router makes use of this functionality to set parameters matched in the request URI into the request object.

[Anmerkung] getParam() retrieves more than user params

In order to do some of its work, getParam() actually retrieves from several sources. In order of priority, these include: user parameters set via setParam(), GET parameters, POST parameters, and finally COOKIE parameters. Be aware of this when pulling data via this method.

7.4.2.2. Basis Url und Unterverzeichnisse

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 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.

[Anmerkung] 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 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:

<?php
/**
 * Dispatch Request with custom base URL with Zend_Controller_Front.
 */
$router     = new Zend_Controller_Router_Rewrite();
$controller = Zend_Controller_Front::getInstance();
$controller->setControllerDirectory('./application/controllers')
           ->setRouter($router)
           ->setBaseUrl('/projects/myapp'); // set the base url!
$response   = $controller->dispatch();
?>

7.4.3. Subclassing the Request Object

The base request class used for all request objects is the abstract class Zend_Controller_Request_Abstract. At its most basic, it defines the following methods:

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();
}

The request object is a container for the request environment. The controller chain really only needs to know how to set and retrieve the controller, action, optional parameters, and dispatched status. By default, the request will search its own parameters using the controller or action keys in order to determine the controller and action.

Extend this class, or one of its derivatives, when you need the request class to interact with a specific environment in order to retrieve data for use in the above tasks. Examples include the HTTP environment, a CLI environment, or a PHP-GTK environment.