Zend_Controller-Request.xml 19 KB

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