| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 17597 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.controller.request">
- <title>Das Request Objekt</title>
- <sect2 id="zend.controller.request.introduction">
- <title>Einführung</title>
- <para>
- Das Request Objekt ist eine einfaches Wertobjekt, das zwischen
- <classname>Zend_Controller_Front</classname> 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 <acronym>HTTP</acronym>, <acronym>CLI</acronym> oder
- <acronym>PHP</acronym>-GTK.
- </para>
- <itemizedlist>
- <listitem><para>
- Auf den Modul Namen kann über <methodname>getModuleName()</methodname> und
- <methodname>setModuleName()</methodname> zugegriffen werden.
- </para></listitem>
- <listitem><para>
- Auf den Controller Namen kann über <methodname>getControllerName()</methodname> und
- <methodname>setControllerName()</methodname> zugegriffen werden.
- </para></listitem>
- <listitem><para>
- Auf den Namen der Aktion, die in diesem Controller aufgerufen wird, kann über
- accessed by <methodname>getActionName()</methodname> und
- <methodname>setActionName()</methodname> zugegriffen werden.
- </para></listitem>
- <listitem><para>
- Parameter, die von der Aktion ansprechbar sind, bestehen aus einem assoziativen
- Array mit Schlüssel und Werte Paaren, auf die komplett per
- <methodname>getParams()</methodname> und <methodname>setParams()</methodname> oder
- einzeln per <methodname>getParam()</methodname> und
- <methodname>setParam()</methodname> zugegriffen werden kann.
- </para></listitem>
- </itemizedlist>
- <para>
- Abhängig vom Typ der Anfrage können auch weitere Methoden verfügbar sein. Das
- verwendete Standard Request Object <classname>Zend_Controller_Request_Http</classname>
- stellt z.B. Methoden zum Abfragen der Request <acronym>URI</acronym>, Pfadinformationen,
- <varname>$_GET</varname> und <varname>$_POST</varname> Parameter usw. bereit.
- </para>
- <para>
- 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.
- </para>
- <para>
- Zusätzlich ist das Request Object besonders beim Testen sehr nützlich. Der Entwickler
- kann die Anfrageumgebung von Hand erstellen, inklusive Controller, Aktion, Parameter,
- <acronym>URI</acronym> usw. und das Request Objekt an den Front Controller übrgeben, um
- den Ablauf der Applikation zu testen. Zusammen mit dem
- <link linkend="zend.controller.response">Response Objekt</link> sind durchdachte und
- genaue Unit Tests für eine <acronym>MVC</acronym> Applikation möglich.
- </para>
- </sect2>
- <sect2 id="zend.controller.request.http">
- <title>HTTP Anfragen</title>
- <sect3 id="zend.controller.request.http.dataacess">
- <title>Auf Request Daten zugreifen</title>
- <para>
- <classname>Zend_Controller_Request_Http</classname> 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 <acronym>URI</acronym>
- ermittelt wurden. Es erlaubt zusätzlich den Zugriff auf superglobale Werte als
- öffentliche Eigenschaften und verwaltet die aktuelle Basis <acronym>URL</acronym>
- und Request <acronym>URI</acronym>. Superglobale Werte können in einem Request
- Objekt nicht gesetzt werden, stattdessen verwendet man die
- <methodname>setParam()</methodname> und <methodname>getParam()</methodname>
- Methoden um Benutzerparameter zu setzen oder zu erhalten.
- </para>
- <note>
- <title>Superglobale Daten</title>
- <para>
- Beim Zugriff auf superglobale Daten über die öffentlichen Eigenschaften von
- <classname>Zend_Controller_Request_Http</classname> ist es notwendig, darauf zu
- achten, dass der Eigenschaftsname (der superglobale Arrayschlüssel) einem
- superglobalen Wert in einer bestimmten Reihenfolge entspricht: 1.
- <constant>GET</constant>, 2. <constant>POST</constant>, 3.
- <constant>COOKIE</constant>, 4. <constant>SERVER</constant>, 5.
- <constant>ENV</constant>.
- </para>
- </note>
- <para>
- Auf spezifische superglobale Werte kann alternativ über eine öffentliche Methode
- zugegriffen werden. Zum Beispiel kann auf den unverarbeitete Wert von
- <varname>$_POST['user']</varname> durch Aufruf der
- <methodname>getPost('user')</methodname> Methode des Request Objekts zugegriffen
- werden. Diese beinhalten <methodname>getQuery()</methodname>, um
- <varname>$_GET</varname> Elemente zu erhalten und
- <methodname>getHeader()</methodname>, um Request Header zu erhalten.
- </para>
- <note>
- <title>GET und POST Daten</title>
- <para>
- Vorsicht wenn auf Daten von einem Anfrage Objekt 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 Anfrage Objekt.
- </para>
- </note>
- <note>
- <title>Empfangen der rohen POST Daten!</title>
- <para>
- Mit 1.5.0 können auch die rohen Post Daten über die
- <methodname>getRawBody()</methodname> Methode empfangen werden. Diese Methode
- gibt <constant>FALSE</constant> zurück wenn keine Daten auf diesem Weg
- übermittelt wurden, andernfalls den kompletten Inhalt von Post.
- </para>
- <para>
- Das ist grundsätzlich sinnvoll um Inhalt zu akzeptieren wenn eine RESTvolle
- <acronym>MVC</acronym> Anwendung entwickelt wird.
- </para>
- </note>
- <para>
- Es können auch Benutzerparameter im Anfrage Objekt gesetzt werden durch Verwendung
- von <methodname>setParam()</methodname> und empfangen derselben später durch
- verwenden von <methodname>getParam()</methodname>. Der Router verwendet diese
- Funktionalität um passende Parameter in der Anfrage <acronym>URI</acronym> im
- Anfrage Objekt zu setzen.
- </para>
- <note>
- <title>getParam() empfängt mehr als Benutzer Parameter</title>
- <para>
- Um einiges Ihrer Arbeit zu tun, empfängt <methodname>getParam()</methodname>
- von verschiedenen Quellen. Je nach Priorität enthalten diese: Benutzer
- Parameter die über <methodname>setParam()</methodname> gesetzt wurden,
- <constant>GET</constant> Parameter, und letztendlich <constant>POST</constant>
- Parameter. Aufpassen vor dem Durchlaufen von Daten mit dieser Methode.
- </para>
- <para>
- Wenn man nur Parameter erhalten will die vorher mit
- <methodname>setParam()</methodname> gesetzt wurden, muß
- <methodname>getUserParam()</methodname> verwendet werden.
- </para>
- <para>
- Zusätzlich, sein 1.5.0, kann gesperrt werden welche Quellparameter gesucht
- werden. <methodname>setParamSources()</methodname> erlaubt es ein leeres Array
- zu spezifizieren oder ein Array mit einem oder mehreren Werten von '_GET' oder
- '_POST' um zu zeigen welche Quellparameter erlaubt sind (standardmäßig sind
- beide erlaubt); Wenn der Zugriff nur auf '_GET' beschränkt werden soll muß
- <methodname>setParamSources(array('_GET'))</methodname> spezifiziert werden.
- </para>
- </note>
- <note>
- <title>Apache Quirks</title>
- <para>
- Wenn Apache's 404 Handler verwendet wird um eingehende Anfragen an den Front
- Controller zu übergeben, oder ein PT Flag mit Rewrite Regeln verwendet wird,
- enthält <varname>$_SERVER['REDIRECT_URL']</varname> die <acronym>URI</acronym>
- die benötigt wird, nicht <varname>$_SERVER['REQUEST_URI']</varname>. Wenn so ein
- Setup verwendet wird und man ungültige Routen erhält, sollte man stattdessen die
- <classname>Zend_Controller_Request_Apache404</classname> Klasse statt der
- standard Http Klasse für das Anfrage Objekt verwenden:
- </para>
- <programlisting language="php"><![CDATA[
- $request = new Zend_Controller_Request_Apache404();
- $front->setRequest($request);
- ]]></programlisting>
- <para>
- Diese Klasse erweitert die <classname>Zend_Controller_Request_Http</classname>
- Klasse und modifiziert einfach die automatische Entdeckung der Anfrage
- <acronym>URI</acronym>. Sie kann als einfache Ersetzung verwendet werden.
- </para>
- </note>
- </sect3>
- <sect3 id="zend.controller.request.http.baseurl">
- <title>Basis Url und Unterverzeichnisse</title>
- <para>
- <classname>Zend_Controller_Request_Http</classname> erlaubt, dass
- <classname>Zend_Controller_Router_Rewrite</classname> in einem Unterverzeichnis
- verwendet werden kann. <classname>Zend_Controller_Request_Http</classname> versucht,
- die Basis <acronym>URL</acronym> automatisch zu erkennen und entsprechend zu setzen.
- </para>
- <para>
- Wenn man zum Beispiel seine <filename>index.php</filename> in einem
- Webserverunterverzeichnis mit Namen <filename>/projects/myapp/index.php</filename>
- verwendet, sollte die Basis <acronym>URL</acronym> (die Rewrite Basis) auf
- <filename>/projects/myapp</filename> 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
- <command>'user/:username'</command> passt auf <acronym>URI</acronym>s wie
- <filename>http://localhost/projects/myapp/user/martel</filename> und
- <filename>http://example.com/user/martel</filename>.
- </para>
- <note>
- <title>URL Erkennung beachtet Groß- und Kleinschreibung</title>
- <para>
- Die automatische Erkennung der Basis <acronym>URL</acronym> beachtet die Groß-
- und Kleinschreibung, weshalb man sicherstellen sollte, dass die
- <acronym>URL</acronym> einem Unterverzeichnis im Dateisystem entspricht (sogar
- auf einem Windows Rechner). Andernfalls wird eine Ausnahme geworfen.
- </para>
- </note>
- <para>
- Sollte die Basis <acronym>URL</acronym> falsch erkannt werden, kann man diese auch
- mit einem eigenen Pfad mit Hilfe der <methodname>setBaseUrl()</methodname> Methode
- der <classname>Zend_Controller_Request_Http</classname> Klasse oder der
- <classname>Zend_Controller_Front</classname> Klasse überschreiben. Die einfachste
- Methode ist die von <classname>Zend_Controller_Front</classname>, welche es an das
- Request Object weiter leitet. Beispiel, um eine eigene Basis <acronym>URL</acronym>
- zu setzen:
- </para>
- <programlisting language="php"><![CDATA[
- /**
- * Dispatch Anfrage mit einer kunden basierenden 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();
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.controller.request.http.method">
- <title>Erkennen der Anfrage Methode</title>
- <para>
- <methodname>getMethod()</methodname> erlaubt es die <acronym>HTTP</acronym> Anfrage
- Methode 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:
- </para>
- <itemizedlist>
- <listitem><para><methodname>isGet()</methodname></para></listitem>
- <listitem><para><methodname>isPost()</methodname></para></listitem>
- <listitem><para><methodname>isPut()</methodname></para></listitem>
- <listitem><para><methodname>isDelete()</methodname></para></listitem>
- <listitem><para><methodname>isHead()</methodname></para></listitem>
- <listitem><para><methodname>isOptions()</methodname></para></listitem>
- </itemizedlist>
- <para>
- Der grundsätzliche Verwendungszweck hierfür ist die Erstellung von RESTvollen
- <acronym>MVC</acronym> Architekturen.
- </para>
- </sect3>
- <sect3 id="zend.controller.request.http.ajax">
- <title>Erkennen von AJAX Anfragen</title>
- <para>
- <classname>Zend_Controller_Request_Http</classname> hat eine rudimentäre Methode für
- die Erkennung von <acronym>AJAX</acronym> Anfragen:
- <methodname>isXmlHttpRequest()</methodname>. Diese Methode sucht nach einem
- <acronym>HTTP</acronym> Anfrageheader <emphasis>X-Requested-With</emphasis> mit dem
- Wert 'XMLHttpRequest'; wenn er gefunden wird, gibt er <constant>TRUE</constant>
- zurück.
- </para>
- <para>
- Aktuell wird dieser Header standardmäßig mit den folgenden JS Bibliotheken
- geschickt:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- Prototype und Scriptaculous (und von Prototype abgeleitete Bibliotheken)
- </para>
- </listitem>
- <listitem><para>Yahoo! UI Library</para></listitem>
- <listitem><para>jQuery</para></listitem>
- <listitem><para>MochiKit</para></listitem>
- </itemizedlist>
- <para>
- Die meisten <acronym>AJAX</acronym> Bibliotheken erlauben das Senden von eigenen
- <acronym>HTTP</acronym> Anfrageheadern; wenn die eigene Bibliothek diesen Header
- nicht sendet, muß dieser einfach beim Anfrageheader hinzugefügt werden um
- sicherzustellen das die <methodname>isXmlHttpRequest()</methodname> Methode
- funktioniert.
- </para>
- </sect3>
- </sect2>
- <sect2 id="zend.controller.request.subclassing">
- <title>Vererben des Anfrage Objektes</title>
- <para>
- Die Basis Anfrage Klasse die für alle Anfrage Objekte verwendet wird ist die abstrakte
- Klasse <classname>Zend_Controller_Request_Abstract</classname>. Sie ist sehr
- grundsätzlich und definiert die folgenden Methoden:
- </para>
- <programlisting language="php"><![CDATA[
- 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();
- }
- ]]></programlisting>
- <para>
- Das Anfrage Objekt ist ein Behälter für die Anfrage Umgebung. 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
- Anfrage Objekt die eigenen Parameter indem es den Controller oder die Aktions Schlüssel
- verwendet um den Controller und die Aktion zu ermitteln.
- </para>
- <para>
- Erweitere diese Klasse, oder eine Ihrer Derivate, wenn die Anfrage Klasse mit einer
- speziellen Umgebung interagieren soll, um Daten für die obigen Aufgaben zu erhalten.
- Beispiele beinhalten <link linkend="zend.controller.request.http">die
- <acronym>HTTP</acronym> Umgebung</link>, eine <acronym>CLI</acronym> Umgebung, oder
- eine <acronym>PHP</acronym>-GTK Umgebung.
- </para>
- </sect2>
- </sect1>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|