1 <?xml version="1.0" encoding="UTF-8"?>
3 <sect1 id="zend.controller.request">
4 <title>The Request Object</title>
6 <sect2 id="zend.controller.request.introduction">
7 <title>Introduction</title>
10 The request object is a simple value object that is passed between
11 <classname>Zend_Controller_Front</classname> and the router, dispatcher, and
12 controller classes. It packages the names of the requested module,
13 controller, action, and optional parameters, as well as the rest of
14 the request environment, be it <acronym>HTTP</acronym>, the <acronym>CLI</acronym>, or
15 <acronym>PHP</acronym>-GTK.
21 The module name is accessed by <methodname>getModuleName()</methodname> and
22 <methodname>setModuleName()</methodname>.
28 The controller name is accessed by <methodname>getControllerName()</methodname>
29 and <methodname>setControllerName()</methodname>.
35 The name of the action to call within that controller is
36 accessed by <methodname>getActionName()</methodname> and
37 <methodname>setActionName()</methodname>.
43 Parameters to be accessible by the action are an associative array
44 of key and value pairs that are retrieved by
45 <methodname>getParams()</methodname> and set with
46 <methodname>setParams()</methodname>, or individually by
47 <methodname>getParam()</methodname> and <methodname>setParam()</methodname>.
53 Based on the type of request, there may be more methods available.
54 The default request used, <classname>Zend_Controller_Request_Http</classname>,
55 for instance, has methods for retrieving the request <acronym>URI</acronym>, path
56 information, <varname>$_GET</varname> and <varname>$_POST</varname> parameters,
61 The request object is passed to the front controller, or if none is
62 provided, it is instantiated at the beginning of the dispatch
63 process, before routing occurs. It is passed through to every object
64 in the dispatch chain.
68 Additionally, the request object is particularly useful in testing.
69 The developer may craft the request environment, including module,
70 controller, action, parameters, <acronym>URI</acronym>, etc, and pass the request
71 object to the front controller to test application flow. When paired
72 with the <link linkend="zend.controller.response">response
73 object</link>, elaborate and precise unit testing of <acronym>MVC</acronym>
74 applications becomes possible.
78 <sect2 id="zend.controller.request.http">
79 <title>HTTP Requests</title>
81 <sect3 id="zend.controller.request.http.dataacess">
82 <title>Accessing Request Data</title>
85 <classname>Zend_Controller_Request_Http</classname> encapsulates access to
86 relevant values such as the key name and value for the
87 controller and action router variables, and all additional
88 parameters parsed from the <acronym>URI</acronym>. It additionally allows access to
89 values contained in the superglobals as public members, and
90 manages the current Base <acronym>URL</acronym> and Request <acronym>URI</acronym>.
91 Superglobal values cannot be set on a request object, instead use the
92 <methodname>setParam()</methodname> and <methodname>getParam()</methodname> methods
93 to set or retrieve user parameters.
97 <title>Superglobal Data</title>
100 When accessing superglobal data through
101 <classname>Zend_Controller_Request_Http</classname> as public member
102 properties, it is necessary to keep in mind that the
103 property name (superglobal array key) is matched to a
104 superglobal in a specific order of precedence: 1. <constant>GET</constant>, 2.
105 <constant>POST</constant>, 3. <constant>COOKIE</constant>, 4.
106 <constant>SERVER</constant>, 5. <constant>ENV</constant>.
111 Specific superglobals can be accessed using a public method as
112 an alternative. For example, the raw value of
113 <varname>$_POST['user']</varname> can be accessed by calling
114 <methodname>getPost('user')</methodname> on the request object. These
115 include <methodname>getQuery()</methodname> for retrieving
116 <varname>$_GET</varname> elements, and <methodname>getHeader()</methodname> for
117 retrieving request headers.
121 <title>GET and POST Data</title>
124 Be cautious when accessing data from the request object as
125 it is not filtered in any way. The router and dispatcher
126 validate and filter data for use with their tasks, but leave
127 the data untouched in the request object.
132 <title>Retrieving the Raw POST Data</title>
135 As of 1.5.0, you can also retrieve the raw post data via the
136 <methodname>getRawBody()</methodname> method. This method returns
137 <constant>FALSE</constant> if no data was submitted in that fashion, but the
138 full body of the post otherwise.
142 This is primarily useful for accepting content when
143 developing a RESTful <acronym>MVC</acronym> application.
148 You may also set user parameters in the request object using
149 <methodname>setParam()</methodname> and retrieve these later using
150 <methodname>getParam()</methodname>. The router makes use of this
151 functionality to set parameters matched in the request <acronym>URI</acronym> into
156 <title>getParam() Retrieves More than User Parameters</title>
159 In order to do some of its work, <methodname>getParam()</methodname> actually
160 retrieves from several sources. In order of priority, these
161 include: user parameters set via <methodname>setParam()</methodname>,
162 <constant>GET</constant> parameters, and finally <constant>POST</constant>
163 parameters. Be aware of this when pulling data via this
168 If you wish to pull only from parameters you set via
169 <methodname>setParam()</methodname>, use the
170 <methodname>getUserParam()</methodname>.
174 Additionally, as of 1.5.0, you can lock down which parameter
175 sources will be searched. <methodname>setParamSources()</methodname>
176 allows you to specify an empty array or an array with one or
177 more of the values '_GET' or '_POST' indicating which
178 parameter sources are allowed (by default, both are
179 allowed); if you wish to restrict access to only '_GET'
180 specify <methodname>setParamSources(array('_GET'))</methodname>.
185 <title>Apache Quirks</title>
188 If you are using Apache's 404 handler to pass incoming
189 requests to the front controller, or using a PT flag with
190 rewrite rules, <varname>$_SERVER['REDIRECT_URL']</varname>
191 contains the <acronym>URI</acronym> you need, not
192 <varname>$_SERVER['REQUEST_URI']</varname>. If you are using such
193 a setup and getting invalid routing, you should use the
194 <classname>Zend_Controller_Request_Apache404</classname> class instead
195 of the default <acronym>HTTP</acronym> class for your request object:
198 <programlisting language="php"><![CDATA[
199 $request = new Zend_Controller_Request_Apache404();
200 $front->setRequest($request);
204 This class extends the
205 <classname>Zend_Controller_Request_Http</classname> class and simply
206 modifies the autodiscovery of the request <acronym>URI</acronym>. It can be
207 used as a drop-in replacement.
212 <sect3 id="zend.controller.request.http.baseurl">
213 <title>Base Url and Subdirectories</title>
216 <classname>Zend_Controller_Request_Http</classname> allows
217 <classname>Zend_Controller_Router_Rewrite</classname> to be used in subdirectories.
218 <classname>Zend_Controller_Request_Http</classname> will attempt to automatically
219 detect your base <acronym>URL</acronym> and set it accordingly.
223 For example, if you keep your <filename>index.php</filename> in a
224 webserver subdirectory named
225 <filename>/projects/myapp/index.php</filename>, base <acronym>URL</acronym> (rewrite
226 base) should be set to <filename>/projects/myapp</filename>. This string will
227 then be stripped from the beginning of the path before
228 calculating any route matches. This frees one from the necessity
229 of prepending it to any of your routes. A route of
230 <command>'user/:username'</command> will match <acronym>URI</acronym>s like
231 <filename>http://localhost/projects/myapp/user/martel</filename> and
232 <filename>http://example.com/user/martel</filename>.
236 <title>URL Detection is Case Sensitive</title>
239 Automatic base <acronym>URL</acronym> detection is case sensitive, so make sure
240 your <acronym>URL</acronym> will match a subdirectory name in a filesystem (even
241 on Windows machines). If it doesn't, an exception will be raised.
246 Should base <acronym>URL</acronym> be detected incorrectly you can override it
247 with your own base path with the help of the
248 <methodname>setBaseUrl()</methodname> method of either the
249 <classname>Zend_Controller_Request_Http</classname> class, or the
250 <classname>Zend_Controller_Front</classname> class. The easiest
251 method is to set it in <classname>Zend_Controller_Front</classname>,
252 which will proxy it into the request object. Example usage to
253 set a custom base <acronym>URL</acronym>:
256 <programlisting language="php"><![CDATA[
258 * Dispatch Request with custom base URL with Zend_Controller_Front.
260 $router = new Zend_Controller_Router_Rewrite();
261 $controller = Zend_Controller_Front::getInstance();
262 $controller->setControllerDirectory('./application/controllers')
264 ->setBaseUrl('/projects/myapp'); // set the base url!
265 $response = $controller->dispatch();
269 <sect3 id="zend.controller.request.http.method">
270 <title>Determining the Request Method</title>
273 <methodname>getMethod()</methodname> allows you to determine the
274 <acronym>HTTP</acronym> request method used to request the current resource.
275 Additionally, a variety of methods exist that allow you to get
276 boolean responses when asking if a specific type of request has
281 <listitem><para><methodname>isGet()</methodname></para></listitem>
282 <listitem><para><methodname>isPost()</methodname></para></listitem>
283 <listitem><para><methodname>isPut()</methodname></para></listitem>
284 <listitem><para><methodname>isDelete()</methodname></para></listitem>
285 <listitem><para><methodname>isHead()</methodname></para></listitem>
286 <listitem><para><methodname>isOptions()</methodname></para></listitem>
290 The primary use case for these is for creating RESTful <acronym>MVC</acronym>
295 <sect3 id="zend.controller.request.http.ajax">
296 <title>Detecting AJAX Requests</title>
299 <classname>Zend_Controller_Request_Http</classname> has a rudimentary
300 method for detecting <acronym>AJAX</acronym> requests:
301 <methodname>isXmlHttpRequest()</methodname>. This method looks for an
302 <acronym>HTTP</acronym> request header <emphasis>X-Requested-With</emphasis> with
303 the value 'XMLHttpRequest'; if found, it returns <constant>TRUE</constant>.
307 Currently, this header is known to be passed by default with the
308 following JS libraries:
313 <para>Prototype and Scriptaculous (and libraries derived from Prototype)</para>
316 <listitem><para>Yahoo! UI Library</para></listitem>
317 <listitem><para>jQuery</para></listitem>
318 <listitem><para>MochiKit</para></listitem>
322 Most <acronym>AJAX</acronym> libraries allow you to send custom
323 <acronym>HTTP</acronym> request headers; if your library does not send this header,
324 simply add it as a request header to ensure the
325 <methodname>isXmlHttpRequest()</methodname> method works for you.
330 <sect2 id="zend.controller.request.subclassing">
331 <title>Subclassing the Request Object</title>
334 The base request class used for all request objects is the abstract
335 class <classname>Zend_Controller_Request_Abstract</classname>. At its most
336 basic, it defines the following methods:
339 <programlisting language="php"><![CDATA[
340 abstract class Zend_Controller_Request_Abstract
345 public function getControllerName();
348 * @param string $value
351 public function setControllerName($value);
356 public function getActionName();
359 * @param string $value
362 public function setActionName($value);
367 public function getControllerKey();
373 public function setControllerKey($key);
378 public function getActionKey();
384 public function setActionKey($key);
390 public function getParam($key);
394 * @param mixed $value
397 public function setParam($key, $value);
402 public function getParams();
405 * @param array $array
408 public function setParams(array $array);
411 * @param boolean $flag
414 public function setDispatched($flag = true);
419 public function isDispatched();
424 The request object is a container for the request environment. The
425 controller chain really only needs to know how to set and retrieve the
426 controller, action, optional parameters, and dispatched status. By
427 default, the request will search its own parameters using the
428 controller or action keys in order to determine the controller and
433 Extend this class, or one of its derivatives, when you need the
434 request class to interact with a specific environment in order to
435 retrieve data for use in the above tasks. Examples include <link
436 linkend="zend.controller.request.http">the <acronym>HTTP</acronym>
437 environment</link>, a <acronym>CLI</acronym> environment, or a
438 <acronym>PHP</acronym>-GTK environment.