[MANUAL] English:
[zend.git] / documentation / manual / en / module_specs / Zend_Controller-Dispatcher.xml
blob7b3b02889f41b0ebd1af2695c3bf8b1a00045dff
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <sect1 id="zend.controller.dispatcher">
4     <title>The Dispatcher</title>
6     <sect2 id="zend.controller.dispatcher.overview">
7         <title>Overview</title>
9         <para>
10             Dispatching is the process of taking the request object,
11             <classname>Zend_Controller_Request_Abstract</classname>, extracting the module
12             name, controller name, action name, and optional parameters
13             contained in it, and then instantiating a controller and calling an
14             action of that controller. If any of the module, controller, or
15             action are not found, it will use default values for them.
16             <classname>Zend_Controller_Dispatcher_Standard</classname> specifies
17             <emphasis>index</emphasis> for each of the controller and action defaults
18             and <emphasis>default</emphasis> for the module default value, but allows
19             the developer to change the default values for each using the
20             <methodname>setDefaultController()</methodname>,
21             <methodname>setDefaultAction()</methodname>, and
22             <methodname>setDefaultModule()</methodname> methods, respectively.
23         </para>
25         <note>
26             <title>Default Module</title>
28             <para>
29                 When creating modular applications, you may find that you want
30                 your default module namespaced as well (the default
31                 configuration is that the default module is
32                 <emphasis>not</emphasis> namespaced). As of 1.5.0, you can now
33                 do so by specifying the <property>prefixDefaultModule</property> as
34                 <constant>TRUE</constant> in either the front controller or your dispatcher:
35             </para>
37             <programlisting language="php"><![CDATA[
38 // In your front controller:
39 $front->setParam('prefixDefaultModule', true);
41 // In your dispatcher:
42 $dispatcher->setParam('prefixDefaultModule', true);
43 ]]></programlisting>
45             <para>
46                 This allows you to re-purpose an existing module to be the
47                 default module for an application.
48             </para>
49         </note>
51         <para>
52             Dispatching happens in a loop in the front controller. Before
53             dispatching occurs, the front controller routes the request to find
54             user specified values for the module, controller, action, and optional
55             parameters. It then enters a dispatch loop, dispatching the request.
56         </para>
58         <para>
59             At the beginning of each iteration, it sets a flag in the request
60             object indicating that the action has been dispatched. If an action
61             or pre or postDispatch plugin resets that flag, the dispatch loop will
62             continue and attempt to dispatch the new request. By changing the
63             controller and/or action in the request and resetting the dispatched
64             flag, the developer may define a chain of requests to perform.
65         </para>
67         <para>
68             The action controller method that controls such dispatching is
69             <methodname>_forward()</methodname>; call this method from any of the
70             <methodname>preDispatch()</methodname>, <methodname>postDispatch()</methodname> or
71             action methods, providing an action, controller,
72             module, and optionally any additional parameters you may wish to
73             send to the new action:
74         </para>
76         <programlisting language="php"><![CDATA[
77 public function fooAction()
79     // forward to another action in the current controller and module:
80     $this->_forward('bar', null, null, array('baz' => 'bogus'));
83 public function barAction()
85     // forward to an action in another controller:
86     // FooController::bazAction(),
87     // in the current module:
88     $this->_forward('baz', 'foo', null, array('baz' => 'bogus'));
91 public function bazAction()
93     // forward to an action in another controller in another module,
94     // Foo_BarController::bazAction():
95     $this->_forward('baz', 'bar', 'foo', array('baz' => 'bogus'));
97 ]]></programlisting>
98     </sect2>
100     <sect2 id="zend.controller.dispatcher.subclassing">
101         <title>Subclassing the Dispatcher</title>
103         <para>
104             <classname>Zend_Controller_Front</classname> will first call the router to
105             determine the first action in the request. It then enters a dispatch
106             loop, which calls on the dispatcher to dispatch the action.
107         </para>
109         <para>
110             The dispatcher needs a variety of data in order to do its work - it
111             needs to know how to format controller and action names, where to
112             look for controller class files, whether or not a provided module
113             name is valid, and an <acronym>API</acronym> for determining if a given request is even
114             dispatchable based on the other information available.
115         </para>
117         <para>
118             <classname>Zend_Controller_Dispatcher_Interface</classname> defines the
119             following methods as required for any dispatcher implementation:
120         </para>
122         <programlisting language="php"><![CDATA[
123 interface Zend_Controller_Dispatcher_Interface
125     /**
126      * Format a string into a controller class name.
127      *
128      * @param string $unformatted
129      * @return string
130      */
131     public function formatControllerName($unformatted);
133     /**
134      * Format a string into an action method name.
135      *
136      * @param string $unformatted
137      * @return string
138      */
139     public function formatActionName($unformatted);
141     /**
142      * Determine if a request is dispatchable
143      *
144      * @param  Zend_Controller_Request_Abstract $request
145      * @return boolean
146      */
147     public function isDispatchable(
148         Zend_Controller_Request_Abstract $request
149     );
151     /**
152      * Set a user parameter (via front controller, or for local use)
153      *
154      * @param string $name
155      * @param mixed $value
156      * @return Zend_Controller_Dispatcher_Interface
157      */
158     public function setParam($name, $value);
160     /**
161      * Set an array of user parameters
162      *
163      * @param array $params
164      * @return Zend_Controller_Dispatcher_Interface
165      */
166     public function setParams(array $params);
168     /**
169      * Retrieve a single user parameter
170      *
171      * @param string $name
172      * @return mixed
173      */
174     public function getParam($name);
176     /**
177      * Retrieve all user parameters
178      *
179      * @return array
180      */
181     public function getParams();
183     /**
184      * Clear the user parameter stack, or a single user parameter
185      *
186      * @param null|string|array single key or array of keys for
187      *        params to clear
188      * @return Zend_Controller_Dispatcher_Interface
189      */
190     public function clearParams($name = null);
192     /**
193      * Set the response object to use, if any
194      *
195      * @param Zend_Controller_Response_Abstract|null $response
196      * @return void
197      */
198     public function setResponse(
199         Zend_Controller_Response_Abstract $response = null
200     );
202     /**
203      * Retrieve the response object, if any
204      *
205      * @return Zend_Controller_Response_Abstract|null
206      */
207     public function getResponse();
209     /**
210      * Add a controller directory to the controller directory stack
211      *
212      * @param string $path
213      * @param string $args
214      * @return Zend_Controller_Dispatcher_Interface
215      */
216     public function addControllerDirectory($path, $args = null);
218     /**
219      * Set the directory (or directories) where controller files are
220      * stored
221      *
222      * @param string|array $dir
223      * @return Zend_Controller_Dispatcher_Interface
224      */
225     public function setControllerDirectory($path);
227     /**
228      * Return the currently set directory(ies) for controller file
229      * lookup
230      *
231      * @return array
232      */
233     public function getControllerDirectory();
235     /**
236      * Dispatch a request to a (module/)controller/action.
237      *
238      * @param  Zend_Controller_Request_Abstract $request
239      * @param  Zend_Controller_Response_Abstract $response
240      * @return Zend_Controller_Request_Abstract|boolean
241      */
242     public function dispatch(
243         Zend_Controller_Request_Abstract $request,
244         Zend_Controller_Response_Abstract $response
245     );
247     /**
248      * Whether or not a given module is valid
249      *
250      * @param string $module
251      * @return boolean
252      */
253     public function isValidModule($module);
255     /**
256      * Retrieve the default module name
257      *
258      * @return string
259      */
260     public function getDefaultModule();
262     /**
263      * Retrieve the default controller name
264      *
265      * @return string
266      */
267     public function getDefaultControllerName();
269     /**
270      * Retrieve the default action
271      *
272      * @return string
273      */
274     public function getDefaultAction();
276 ]]></programlisting>
278         <para>
279             In most cases, however, you should simply extend the abstract class
280             <classname>Zend_Controller_Dispatcher_Abstract</classname>, in which each of
281             these have already been defined, or
282             <classname>Zend_Controller_Dispatcher_Standard</classname> to modify
283             functionality of the standard dispatcher.
284         </para>
286         <para>
287             Possible reasons to subclass the dispatcher include a desire to
288             use a different class or method naming schema in your action
289             controllers, or a desire to use a different dispatching paradigm
290             such as dispatching to action files under controller directories
291             (instead of dispatching to class methods).
292         </para>
293     </sect2>
294 </sect1>
295 <!--
296 vim:se ts=4 sw=4 et: