Zend_Controller-Request.xml 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 15719 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.controller.request">
  5. <title>Das Request Objekt</title>
  6. <sect2 id="zend.controller.request.introduction">
  7. <title>Einführung</title>
  8. <para>
  9. Das Request Objekt ist eine einfaches Wertobjekt, das zwischen
  10. <classname>Zend_Controller_Front</classname> und den Router, Dispatcher und Controller
  11. Klassen übergeben wird. Es enthält sowohl die Definition des Controllers, der Aktion und
  12. der Parameter, die an die Aktion übergeben werden sollen, als auch den Rest der
  13. Anfrageumgebung, seit es HTTP, CLI oder PHP-GTK.
  14. </para>
  15. <itemizedlist>
  16. <listitem><para>
  17. Auf den Modul Namen kann über <code>getModuleName()</code> und
  18. <code>setModuleName()</code> zugegriffen werden.
  19. </para></listitem>
  20. <listitem><para>
  21. Auf den Controller Namen kann über <code>getControllerName()</code> und
  22. <code>setControllerName()</code> zugegriffen werden.
  23. </para></listitem>
  24. <listitem><para>
  25. Auf den Namen der Aktion, die in diesem Controller aufgerufen wird, kann über
  26. accessed by <code>getActionName()</code> und <code>setActionName()</code>
  27. zugegriffen werden.
  28. </para></listitem>
  29. <listitem><para>
  30. Parameter, die von der Aktion ansprechbar sind, bestehen aus einem assoziativen
  31. Array mit Schlüssel/Wert Paaren, auf die komplett per <code>getParams()</code> und
  32. <code>setParams()</code> oder einzeln per <code>getParam()</code> und
  33. <code>setParam()</code> zugegriffen werden kann.
  34. </para></listitem>
  35. </itemizedlist>
  36. <para>
  37. Abhängig vom Typ der Anfrage können auch weitere Methoden verfügbar sein. Das
  38. verwendete Standard Request Object <classname>Zend_Controller_Request_Http</classname>
  39. stellt z.B. Methoden zum Abfragen der Request URI, Pfadinformationen,
  40. <varname>$_GET</varname> und <varname>$_POST</varname> Parameter usw. bereit.
  41. </para>
  42. <para>
  43. Das Request Objekt wird an den Front Controller übergeben oder, wenn keines bereit
  44. gestellt wurde, am Anfang des Dispatcher Prozesses instanziert, bevor das Routing
  45. beginnt. Es wird an jedes Objekt in der Dispatcherkette übergeben.
  46. </para>
  47. <para>
  48. Zusätzlich ist das Request Object besonders beim Testen sehr nützlich. Der Entwickler
  49. kann die Anfrageumgebung von Hand erstellen, inklusive Controller, Aktion, Parameter,
  50. URI usw. und das Request Objekt an den Front Controller übrgeben, um den Ablauf der
  51. Applikation zu testen. Zusammen mit dem
  52. <link linkend="zend.controller.response">Response Objekt</link> sind durchdachte und
  53. genaue Unit Tests für eine MVC Applikation möglich.
  54. </para>
  55. </sect2>
  56. <sect2 id="zend.controller.request.http">
  57. <title>HTTP Anfragen</title>
  58. <sect3 id="zend.controller.request.http.dataacess">
  59. <title>Auf Request Daten zugreifen</title>
  60. <para>
  61. <classname>Zend_Controller_Request_Http</classname> kapselt den Zugriff auf
  62. relevante Werte wie der Schlüssel und Wert für Controller und Action Variablen des
  63. Routers und alle zusätzlichen Parameter, die aus der URI ermittelt wurden. Es
  64. erlaubt zusätzlich den Zugriff auf superglobale Werte als öffentliche Eigenschaften
  65. und verwaltet die aktuelle Basis URL und Request URI. Superglobale Werte können in
  66. einem Request Objekt nicht gesetzt werden, stattdessen verwendet man die
  67. setParam/getParam Methoden um Benutzerparameter zu setzen oder zu erhalten.
  68. </para>
  69. <note>
  70. <title>Superglobale Daten</title>
  71. <para>
  72. Beim Zugriff auf superglobale Daten über die öffentlichen Eigenschaften von
  73. <classname>Zend_Controller_Request_Http</classname> ist es notwendig, darauf zu
  74. achten, dass der Eigenschaftsname (der superglobale Arrayschlüssel) einem
  75. superglobalen Wert in einer bestimmten Reihenfolge entspricht: 1. GET, 2. POST,
  76. 3. COOKIE, 4. SERVER, 5. ENV.
  77. </para>
  78. </note>
  79. <para>
  80. Auf spezifische superglobale Werte kann alternativ über eine öffentliche Methode
  81. zugegriffen werden. Zum Beispiel kann auf den unverarbeitete Wert von
  82. <varname>$_POST['user']</varname> durch Aufruf der <code>getPost('user')</code>
  83. Methode des Request Objekts zugegriffen werden. Diese beinhalten
  84. <code>getQuery()</code>, um <varname>$_GET</varname> Elemente zu erhalten und
  85. <code>getHeader()</code>, um Request Header zu erhalten.
  86. </para>
  87. <note>
  88. <title>GET und POST Daten</title>
  89. <para>
  90. Vorsicht wenn auf Daten von einem Anfrage Objekt zugegriffen wird da diese in
  91. keiner Weise gefiltert werden. Der Router und Dispatcher prüfen und filtern
  92. Daten für die Verwendung innerhalb Ihrer Aufgabe, lassen diese Daten aber
  93. unangetastet im Anfrage Objekt.
  94. </para>
  95. </note>
  96. <note>
  97. <title>Empfangen der rohen POST Daten!</title>
  98. <para>
  99. Mit 1.5.0 können auch die rohen Post Daten über die <code>getRawBody()</code>
  100. Methode empfangen werden. Diese Methode gibt false zurück wenn keine Daten auf
  101. diesem Weg übermittelt wurden, andernfalls den kompletten Inhalt von Post.
  102. </para>
  103. <para>
  104. Das ist grundsätzlich sinnvoll um Inhalt zu akzeptieren wenn eine RESTvolle MVC
  105. Anwendung entwickelt wird.
  106. </para>
  107. </note>
  108. <para>
  109. Es können auch Benutzerparameter im Anfrage Objekt gesetzt werden durch Verwendung
  110. von <code>setParam()</code> und empfangen derselben später durch verwenden von
  111. <code>getParam()</code>. Der Router verwendet diese Funktionalität um passende
  112. Parameter in der Anfrage URI im Anfrage Objekt zu setzen.
  113. </para>
  114. <note>
  115. <title>getParam() empfängt mehr als Benutzer Parameter</title>
  116. <para>
  117. Um einiges Ihrer Arbeit zu tun, empfängt <code>getParam()</code> von
  118. verschiedenen Quellen. Je nach Priorität enthalten diese: Benutzer Parameter
  119. die über <code>setParam()</code> gesetzt wurden, <code>GET</code> Parameter,
  120. und letztendlich <code>POST</code> Parameter. Aufpassen vor dem Durchlaufen von
  121. Daten mit dieser Methode.
  122. </para>
  123. <para>
  124. Wenn man nur Parameter erhalten will die vorher mit <code>setParam()</code>
  125. gesetzt wurden, muß <code>getUserParam()</code> verwendet werden.
  126. </para>
  127. <para>
  128. Zusätzlich, sein 1.5.0, kann gesperrt werden welche Quellparameter gesucht
  129. werden. <code>setParamSources()</code> erlaubt es ein leeres Array zu
  130. spezifizieren oder ein Array mit einem oder mehreren Werten von '_GET' oder
  131. '_POST' um zu zeigen welche Quellparameter erlaubt sind (standardmäßig sind
  132. beide erlaubt); Wenn der Zugriff nur auf '_GET' beschränkt werden soll muß
  133. <code>setParamSources(array('_GET'))</code> spezifiziert werden.
  134. </para>
  135. </note>
  136. <note>
  137. <title>Apache Quirks</title>
  138. <para>
  139. Wenn Apache's 404 Handler verwendet wird um eingehende Anfragen an den Front
  140. Controller zu übergeben, oder ein PT Flag mit Rewrite Regeln verwendet wird,
  141. enthält <varname>$_SERVER['REDIRECT_URL']</varname> die URI die benötigt wird,
  142. nicht <varname>$_SERVER['REQUEST_URI']</varname>. Wenn so ein Setup verwendet
  143. wird und man ungültige Routen erhält, sollte man stattdessen die
  144. <classname>Zend_Controller_Request_Apache404</classname> Klasse statt der
  145. standard Http Klasse für das Anfrage Objekt verwenden:
  146. </para>
  147. <programlisting language="php"><![CDATA[
  148. $request = new Zend_Controller_Request_Apache404();
  149. $front->setRequest($request);
  150. ]]></programlisting>
  151. <para>
  152. Diese Klasse erweitert die <classname>Zend_Controller_Request_Http</classname>
  153. Klasse und modifiziert einfach die automatische Entdeckung der Anfrage URI. Sie
  154. kann als einfache Ersetzung verwendet werden.
  155. </para>
  156. </note>
  157. </sect3>
  158. <sect3 id="zend.controller.request.http.baseurl">
  159. <title>Basis Url und Unterverzeichnisse</title>
  160. <para>
  161. <classname>Zend_Controller_Request_Http</classname> erlaubt, dass
  162. <classname>Zend_Controller_Router_Rewrite</classname> in einem Unterverzeichnis
  163. verwendet werden kann. <classname>Zend_Controller_Request_Http</classname> versucht,
  164. die Basis URL automatisch zu erkennen und entsprechend zu setzen.
  165. </para>
  166. <para>
  167. Wenn man zum Beispiel seine <code>index.php</code> in einem
  168. Webserverunterverzeichnis mit Namen <code>/projects/myapp/index.php</code>
  169. verwendet, sollte die Basis URL (die Rewrite Basis) auf <code>/projects/myapp</code>
  170. gesetzt werden. Dieser String wird dann vom Anfang des Pfades entfernt, bevor irgend
  171. welche Routingtreffer ermittelt werden. Dies befreit einem davon, es an den Anfang
  172. jeder Route setzen zu müssen. Eine Route <code>'user/:username'</code> passt auf
  173. URIs wie <code>http://localhost/projects/myapp/user/martel</code> und
  174. <code>http://example.com/user/martel</code>.
  175. </para>
  176. <note>
  177. <title>URL Erkennung beachtet Groß- und Kleinschreibung</title>
  178. <para>
  179. Die automatische Erkennung der Basis URL beachtet die Groß- und Kleinschreibung,
  180. weshalb man sicherstellen sollte, dass die URL einem Unterverzeichnis im
  181. Dateisystem entspricht (sogar auf einem Windows Rechner). Andernfalls wird eine
  182. Ausnahme geworfen.
  183. </para>
  184. </note>
  185. <para>
  186. Sollte die Basis URL falsch erkannt werden, kann man diese auch mit einem eigenen
  187. Pfad mit Hilfe der <code>setBaseUrl()</code> Methode der
  188. <classname>Zend_Controller_Request_Http</classname> Klasse oder der
  189. <classname>Zend_Controller_Front</classname> Klasse überschreiben. Die einfachste
  190. Methode ist die von <classname>Zend_Controller_Front</classname>, welche es an das
  191. Request Object weiter leitet. Beispiel, um eine eigene Basis URL zu setzen:
  192. </para>
  193. <programlisting language="php"><![CDATA[
  194. /**
  195. * Dispatch Anfrage mit einer kunden basierenden URL mit Zend_Controller_Front.
  196. */
  197. $router = new Zend_Controller_Router_Rewrite();
  198. $controller = Zend_Controller_Front::getInstance();
  199. $controller->setControllerDirectory('./application/controllers')
  200. ->setRouter($router)
  201. ->setBaseUrl('/projects/myapp'); // Setze die Basis URL!
  202. $response = $controller->dispatch();
  203. ]]></programlisting>
  204. </sect3>
  205. <sect3 id="zend.controller.request.http.method">
  206. <title>Erkennen der Anfrage Methode</title>
  207. <para>
  208. <code>getMethod()</code> erlaubt es die HTTP Anfrage Methode zu erkennen die
  209. verwendet wurde um die aktuelle Ressource anzufragen. Zusätzlich existiert eine
  210. Vielzahl von Methoden die es erlauben boolsche Antworten zu erhalten wenn gefragt
  211. wird ob ein spezieller Typ von Anfrage durchgeführt wurde:
  212. </para>
  213. <itemizedlist>
  214. <listitem><para><code>isGet()</code></para></listitem>
  215. <listitem><para><code>isPost()</code></para></listitem>
  216. <listitem><para><code>isPut()</code></para></listitem>
  217. <listitem><para><code>isDelete()</code></para></listitem>
  218. <listitem><para><code>isHead()</code></para></listitem>
  219. <listitem><para><code>isOptions()</code></para></listitem>
  220. </itemizedlist>
  221. <para>
  222. Der grundsätzliche Verwendungszweck hierfür ist die Erstellung von RESTvollen MVC
  223. Architekturen.
  224. </para>
  225. </sect3>
  226. <sect3 id="zend.controller.request.http.ajax">
  227. <title>Erkennen von AJAX Anfragen</title>
  228. <para>
  229. <classname>Zend_Controller_Request_Http</classname> hat eine rudimentäre Methode für
  230. die Erkennung von AJAX Anfragen: <code>isXmlHttpRequest()</code>. Diese Methode
  231. sucht nach einem HTTP Anfrageheader <code>X-Requested-With</code> mit dem Wert
  232. 'XMLHttpRequest'; wenn er gefunden wird, gibt er true zurück.
  233. </para>
  234. <para>
  235. Aktuell wird dieser Header standardmäßig mit den folgenden JS Bibliotheken
  236. geschickt:
  237. </para>
  238. <itemizedlist>
  239. <listitem>
  240. <para>
  241. Prototype/Scriptaculous (und von Prototype abgeleitete Bibliotheken)
  242. </para>
  243. </listitem>
  244. <listitem><para>Yahoo! UI Library</para></listitem>
  245. <listitem><para>jQuery</para></listitem>
  246. <listitem><para>MochiKit</para></listitem>
  247. </itemizedlist>
  248. <para>
  249. Die meisten AJAX Bibliotheken erlauben das Senden von eigenen HTTP Anfrageheadern;
  250. wenn die eigene Bibliothek diesen Header nicht sendet, muß dieser einfach beim
  251. Anfrageheader hinzugefügt werden um sicherzustellen das die
  252. <code>isXmlHttpRequest()</code> Methode funktioniert.
  253. </para>
  254. </sect3>
  255. </sect2>
  256. <sect2 id="zend.controller.request.subclassing">
  257. <title>Vererben des Anfrage Objektes</title>
  258. <para>
  259. Die Basis Anfrage Klasse die für alle Anfrage Objekte verwendet wird ist die abstrakte
  260. Klasse <classname>Zend_Controller_Request_Abstract</classname>. Sie ist sehr
  261. grundsätzlich und definiert die folgenden Methoden:
  262. </para>
  263. <programlisting language="php"><![CDATA[
  264. abstract class Zend_Controller_Request_Abstract
  265. {
  266. /**
  267. * @return string
  268. */
  269. public function getControllerName();
  270. /**
  271. * @param string $value
  272. * @return self
  273. */
  274. public function setControllerName($value);
  275. /**
  276. * @return string
  277. */
  278. public function getActionName();
  279. /**
  280. * @param string $value
  281. * @return self
  282. */
  283. public function setActionName($value);
  284. /**
  285. * @return string
  286. */
  287. public function getControllerKey();
  288. /**
  289. * @param string $key
  290. * @return self
  291. */
  292. public function setControllerKey($key);
  293. /**
  294. * @return string
  295. */
  296. public function getActionKey();
  297. /**
  298. * @param string $key
  299. * @return self
  300. */
  301. public function setActionKey($key);
  302. /**
  303. * @param string $key
  304. * @return mixed
  305. */
  306. public function getParam($key);
  307. /**
  308. * @param string $key
  309. * @param mixed $value
  310. * @return self
  311. */
  312. public function setParam($key, $value);
  313. /**
  314. * @return array
  315. */
  316. public function getParams();
  317. /**
  318. * @param array $array
  319. * @return self
  320. */
  321. public function setParams(array $array);
  322. /**
  323. * @param boolean $flag
  324. * @return self
  325. */
  326. public function setDispatched($flag = true);
  327. /**
  328. * @return boolean
  329. */
  330. public function isDispatched();
  331. }
  332. ]]></programlisting>
  333. <para>
  334. Das Anfrage Objekt ist ein Behälter für die Anfrage Umgebung. Die Controller Kette muß
  335. wirklich nur wissen wie der Controller, die Aktion, die optionalen Parameter und der
  336. Dispatched Status gesetzt und empfangen werden können. Standardmäßig durchsucht das
  337. Anfrage Objekt die eigenen Parameter indem es den Controller oder die Aktions Schlüssel
  338. verwendet um den Controller und die Aktion zu ermitteln.
  339. </para>
  340. <para>
  341. Erweitere diese Klasse, oder eine Ihrer Derivate, wenn die Anfrage Klasse mit einer
  342. speziellen Umgebung interagieren soll, um Daten für die obigen Aufgaben zu erhalten.
  343. Beispiele beinhalten <link linkend="zend.controller.request.http">die HTTP
  344. Umgebung</link>, eine CLI Umgebung, oder eine PHP-GTK Umgebung.
  345. </para>
  346. </sect2>
  347. </sect1>
  348. <!--
  349. vim:se ts=4 sw=4 et:
  350. -->