2
0

Zend_Controller-Request.xml 19 KB

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