Zend_Controller-Request.xml 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect1 id="zend.controller.request">
  4. <title>The Request Object</title>
  5. <sect2 id="zend.controller.request.introduction">
  6. <title>Introduction</title>
  7. <para>
  8. The request object is a simple value object that is passed between
  9. <classname>Zend_Controller_Front</classname> and the router, dispatcher, and
  10. controller classes. It packages the names of the requested module,
  11. controller, action, and optional parameters, as well as the rest of
  12. the request environment, be it HTTP, the CLI, or PHP-GTK.
  13. </para>
  14. <itemizedlist>
  15. <listitem><para>
  16. The module name is accessed by
  17. <code>getModuleName()</code> and
  18. <code>setModuleName()</code>.
  19. </para></listitem>
  20. <listitem><para>
  21. The controller name is accessed by
  22. <code>getControllerName()</code> and
  23. <code>setControllerName()</code>.
  24. </para></listitem>
  25. <listitem><para>
  26. The name of the action to call within that controller is
  27. accessed by <code>getActionName()</code> and
  28. <code>setActionName()</code>.
  29. </para></listitem>
  30. <listitem><para>
  31. Parameters to be accessible by the action are an associative array
  32. of key/value pairs that are retrieved by <code>getParams()</code>
  33. and set with <code>setParams()</code>, or individually by
  34. <code>getParam()</code> and <code>setParam()</code>.
  35. </para></listitem>
  36. </itemizedlist>
  37. <para>
  38. Based on the type of request, there may be more methods available.
  39. The default request used, <classname>Zend_Controller_Request_Http</classname>,
  40. for instance, has methods for retrieving the request URI, path
  41. information, <varname>$_GET</varname> and <varname>$_POST</varname> parameters,
  42. etc.
  43. </para>
  44. <para>
  45. The request object is passed to the front controller, or if none is
  46. provided, it is instantiated at the beginning of the dispatch
  47. process, before routing occurs. It is passed through to every object
  48. in the dispatch chain.
  49. </para>
  50. <para>
  51. Additionally, the request object is particularly useful in testing.
  52. The developer may craft the request environment, including module,
  53. controller, action, parameters, URI, etc, and pass the request
  54. object to the front controller to test application flow. When paired
  55. with the <link linkend="zend.controller.response">response
  56. object</link>, elaborate and precise unit testing of MVC
  57. applications becomes possible.
  58. </para>
  59. </sect2>
  60. <sect2 id="zend.controller.request.http">
  61. <title>HTTP Requests</title>
  62. <sect3 id="zend.controller.request.http.dataacess">
  63. <title>Accessing Request Data</title>
  64. <para>
  65. <classname>Zend_Controller_Request_Http</classname> encapsulates access to
  66. relevant values such as the key name and value for the
  67. controller and action router variables, and all additional
  68. parameters parsed from the URI. It additionally allows access to
  69. values contained in the superglobals as public members, and
  70. manages the current Base URL and Request URI. Superglobal
  71. values cannot be set on a request object, instead use the
  72. setParam/getParam methods to set or retrieve user parameters.
  73. </para>
  74. <note>
  75. <title>Superglobal Data</title>
  76. <para>
  77. When accessing superglobal data through
  78. <classname>Zend_Controller_Request_Http</classname> as public member
  79. properties, it is necessary to keep in mind that the
  80. property name (superglobal array key) is matched to a
  81. superglobal in a specific order of precedence: 1. GET, 2.
  82. POST, 3. COOKIE, 4. SERVER, 5. ENV.
  83. </para>
  84. </note>
  85. <para>
  86. Specific superglobals can be accessed using a public method as
  87. an alternative. For example, the raw value of
  88. <varname>$_POST['user']</varname> can be accessed by calling
  89. <code>getPost('user')</code> on the request object. These
  90. include <code>getQuery()</code> for retrieving
  91. <varname>$_GET</varname> elements, and <code>getHeader()</code> for
  92. retrieving request headers.
  93. </para>
  94. <note>
  95. <title>GET and POST Data</title>
  96. <para>
  97. Be cautious when accessing data from the request object as
  98. it is not filtered in any way. The router and dispatcher
  99. validate and filter data for use with their tasks, but leave
  100. the data untouched in the request object.
  101. </para>
  102. </note>
  103. <note>
  104. <title>Retrieving the Raw POST Data</title>
  105. <para>
  106. As of 1.5.0, you can also retrieve the raw post data via the
  107. <code>getRawBody()</code> method. This method returns false
  108. if no data was submitted in that fashion, but the full body
  109. of the post otherwise.
  110. </para>
  111. <para>
  112. This is primarily useful for accepting content when
  113. developing a RESTful MVC application.
  114. </para>
  115. </note>
  116. <para>
  117. You may also set user parameters in the request object using
  118. <code>setParam()</code> and retrieve these later using
  119. <code>getParam()</code>. The router makes use of this
  120. functionality to set parameters matched in the request URI into
  121. the request object.
  122. </para>
  123. <note>
  124. <title>getParam() Retrieves More than User Parameters</title>
  125. <para>
  126. In order to do some of its work, <code>getParam()</code> actually
  127. retrieves from several sources. In order of priority, these
  128. include: user parameters set via <code>setParam()</code>,
  129. <code>GET</code> parameters, and finally <code>POST</code>
  130. parameters. Be aware of this when pulling data via this
  131. method.
  132. </para>
  133. <para>
  134. If you wish to pull only from parameters you set via
  135. <code>setParam()</code>, use the <code>getUserParam()</code>.
  136. </para>
  137. <para>
  138. Additionally, as of 1.5.0, you can lock down which parameter
  139. sources will be searched. <code>setParamSources()</code>
  140. allows you to specify an empty array or an array with one or
  141. more of the values '_GET' or '_POST' indicating which
  142. parameter sources are allowed (by default, both are
  143. allowed); if you wish to restrict access to only '_GET'
  144. specify <code>setParamSources(array('_GET'))</code>.
  145. </para>
  146. </note>
  147. <note>
  148. <title>Apache Quirks</title>
  149. <para>
  150. If you are using Apache's 404 handler to pass incoming
  151. requests to the front controller, or using a PT flag with
  152. rewrite rules, <varname>$_SERVER['REDIRECT_URL']</varname>
  153. contains the URI you need, not
  154. <varname>$_SERVER['REQUEST_URI']</varname>. If you are using such
  155. a setup and getting invalid routing, you should use the
  156. <classname>Zend_Controller_Request_Apache404</classname> class instead
  157. of the default Http class for your request object:
  158. </para>
  159. <programlisting language="php"><![CDATA[
  160. $request = new Zend_Controller_Request_Apache404();
  161. $front->setRequest($request);
  162. ]]></programlisting>
  163. <para>
  164. This class extends the
  165. <classname>Zend_Controller_Request_Http</classname> class and simply
  166. modifies the autodiscovery of the request URI. It can be
  167. used as a drop-in replacement.
  168. </para>
  169. </note>
  170. </sect3>
  171. <sect3 id="zend.controller.request.http.baseurl">
  172. <title>Base Url and Subdirectories</title>
  173. <para>
  174. <classname>Zend_Controller_Request_Http</classname> allows
  175. <classname>Zend_Controller_Router_Rewrite</classname> to be used in subdirectories.
  176. <classname>Zend_Controller_Request_Http</classname> will attempt to automatically
  177. detect your base URL and set it accordingly.
  178. </para>
  179. <para>
  180. For example, if you keep your <code>index.php</code> in a
  181. webserver subdirectory named
  182. <code>/projects/myapp/index.php</code>, base URL (rewrite base)
  183. should be set to <code>/projects/myapp</code>. This string will
  184. then be stripped from the beginning of the path before
  185. calculating any route matches. This frees one from the necessity
  186. of prepending it to any of your routes. A route of
  187. <code>'user/:username'</code> will match URIs like
  188. <code>http://localhost/projects/myapp/user/martel</code> and
  189. <code>http://example.com/user/martel</code>.
  190. </para>
  191. <note>
  192. <title>URL Detection is Case Sensitive</title>
  193. <para>
  194. Automatic base URL detection is case sensitive, so make sure your URL
  195. will match a subdirectory name in a filesystem (even on Windows
  196. machines). If it doesn't, an exception will be raised.
  197. </para>
  198. </note>
  199. <para>
  200. Should base URL be detected incorrectly you can override it
  201. with your own base path with the help of the
  202. <code>setBaseUrl()</code> method of either the
  203. <classname>Zend_Controller_Request_Http</classname> class, or the
  204. <classname>Zend_Controller_Front</classname> class. The easiest
  205. method is to set it in <classname>Zend_Controller_Front</classname>,
  206. which will proxy it into the request object. Example usage to
  207. set a custom base URL:
  208. </para>
  209. <programlisting language="php"><![CDATA[
  210. /**
  211. * Dispatch Request with custom base URL with Zend_Controller_Front.
  212. */
  213. $router = new Zend_Controller_Router_Rewrite();
  214. $controller = Zend_Controller_Front::getInstance();
  215. $controller->setControllerDirectory('./application/controllers')
  216. ->setRouter($router)
  217. ->setBaseUrl('/projects/myapp'); // set the base url!
  218. $response = $controller->dispatch();
  219. ]]></programlisting>
  220. </sect3>
  221. <sect3 id="zend.controller.request.http.method">
  222. <title>Determining the Request Method</title>
  223. <para>
  224. <code>getMethod()</code> allows you to determine the HTTP
  225. request method used to request the current resource.
  226. Additionally, a variety of methods exist that allow you to get
  227. boolean responses when asking if a specific type of request has
  228. been made:
  229. </para>
  230. <itemizedlist>
  231. <listitem><para><code>isGet()</code></para></listitem>
  232. <listitem><para><code>isPost()</code></para></listitem>
  233. <listitem><para><code>isPut()</code></para></listitem>
  234. <listitem><para><code>isDelete()</code></para></listitem>
  235. <listitem><para><code>isHead()</code></para></listitem>
  236. <listitem><para><code>isOptions()</code></para></listitem>
  237. </itemizedlist>
  238. <para>
  239. The primary use case for these is for creating RESTful MVC
  240. architectures.
  241. </para>
  242. </sect3>
  243. <sect3 id="zend.controller.request.http.ajax">
  244. <title>Detecting AJAX Requests</title>
  245. <para>
  246. <classname>Zend_Controller_Request_Http</classname> has a rudimentary
  247. method for detecting AJAX requests:
  248. <code>isXmlHttpRequest()</code>. This method looks for an
  249. HTTP request header <code>X-Requested-With</code> with the value
  250. 'XMLHttpRequest'; if found, it returns true.
  251. </para>
  252. <para>
  253. Currently, this header is known to be passed by default with the
  254. following JS libraries:
  255. </para>
  256. <itemizedlist>
  257. <listitem><para>Prototype/Scriptaculous (and libraries derived
  258. from Prototype)</para></listitem>
  259. <listitem><para>Yahoo! UI Library</para></listitem>
  260. <listitem><para>jQuery</para></listitem>
  261. <listitem><para>MochiKit</para></listitem>
  262. </itemizedlist>
  263. <para>
  264. Most AJAX libraries allow you to send custom HTTP request
  265. headers; if your library does not send this header, simply add
  266. it as a request header to ensure the
  267. <code>isXmlHttpRequest()</code> method works for you.
  268. </para>
  269. </sect3>
  270. </sect2>
  271. <sect2 id="zend.controller.request.subclassing">
  272. <title>Subclassing the Request Object</title>
  273. <para>
  274. The base request class used for all request objects is the abstract
  275. class <classname>Zend_Controller_Request_Abstract</classname>. At its most
  276. basic, it defines the following methods:
  277. </para>
  278. <programlisting language="php"><![CDATA[
  279. abstract class Zend_Controller_Request_Abstract
  280. {
  281. /**
  282. * @return string
  283. */
  284. public function getControllerName();
  285. /**
  286. * @param string $value
  287. * @return self
  288. */
  289. public function setControllerName($value);
  290. /**
  291. * @return string
  292. */
  293. public function getActionName();
  294. /**
  295. * @param string $value
  296. * @return self
  297. */
  298. public function setActionName($value);
  299. /**
  300. * @return string
  301. */
  302. public function getControllerKey();
  303. /**
  304. * @param string $key
  305. * @return self
  306. */
  307. public function setControllerKey($key);
  308. /**
  309. * @return string
  310. */
  311. public function getActionKey();
  312. /**
  313. * @param string $key
  314. * @return self
  315. */
  316. public function setActionKey($key);
  317. /**
  318. * @param string $key
  319. * @return mixed
  320. */
  321. public function getParam($key);
  322. /**
  323. * @param string $key
  324. * @param mixed $value
  325. * @return self
  326. */
  327. public function setParam($key, $value);
  328. /**
  329. * @return array
  330. */
  331. public function getParams();
  332. /**
  333. * @param array $array
  334. * @return self
  335. */
  336. public function setParams(array $array);
  337. /**
  338. * @param boolean $flag
  339. * @return self
  340. */
  341. public function setDispatched($flag = true);
  342. /**
  343. * @return boolean
  344. */
  345. public function isDispatched();
  346. }
  347. ]]></programlisting>
  348. <para>
  349. The request object is a container for the request environment. The
  350. controller chain really only needs to know how to set and retrieve the
  351. controller, action, optional parameters, and dispatched status. By
  352. default, the request will search its own parameters using the
  353. controller or action keys in order to determine the controller and
  354. action.
  355. </para>
  356. <para>
  357. Extend this class, or one of its derivatives, when you need the
  358. request class to interact with a specific environment in order to
  359. retrieve data for use in the above tasks. Examples include <link
  360. linkend="zend.controller.request.http">the HTTP
  361. environment</link>, a CLI environment, or a PHP-GTK environment.
  362. </para>
  363. </sect2>
  364. </sect1>
  365. <!--
  366. vim:se ts=4 sw=4 et:
  367. -->