1 <?xml version="1.0" encoding="UTF-8"?>
3 <sect1 id="zend.controller.dispatcher">
4 <title>The Dispatcher</title>
6 <sect2 id="zend.controller.dispatcher.overview">
7 <title>Overview</title>
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.
26 <title>Default Module</title>
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:
37 <programlisting language="php"><![CDATA[
38 // In your front controller:
39 $front->setParam('prefixDefaultModule', true);
41 // In your dispatcher:
42 $dispatcher->setParam('prefixDefaultModule', true);
46 This allows you to re-purpose an existing module to be the
47 default module for an application.
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.
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.
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:
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'));
100 <sect2 id="zend.controller.dispatcher.subclassing">
101 <title>Subclassing the Dispatcher</title>
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.
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.
118 <classname>Zend_Controller_Dispatcher_Interface</classname> defines the
119 following methods as required for any dispatcher implementation:
122 <programlisting language="php"><![CDATA[
123 interface Zend_Controller_Dispatcher_Interface
126 * Format a string into a controller class name.
128 * @param string $unformatted
131 public function formatControllerName($unformatted);
134 * Format a string into an action method name.
136 * @param string $unformatted
139 public function formatActionName($unformatted);
142 * Determine if a request is dispatchable
144 * @param Zend_Controller_Request_Abstract $request
147 public function isDispatchable(
148 Zend_Controller_Request_Abstract $request
152 * Set a user parameter (via front controller, or for local use)
154 * @param string $name
155 * @param mixed $value
156 * @return Zend_Controller_Dispatcher_Interface
158 public function setParam($name, $value);
161 * Set an array of user parameters
163 * @param array $params
164 * @return Zend_Controller_Dispatcher_Interface
166 public function setParams(array $params);
169 * Retrieve a single user parameter
171 * @param string $name
174 public function getParam($name);
177 * Retrieve all user parameters
181 public function getParams();
184 * Clear the user parameter stack, or a single user parameter
186 * @param null|string|array single key or array of keys for
188 * @return Zend_Controller_Dispatcher_Interface
190 public function clearParams($name = null);
193 * Set the response object to use, if any
195 * @param Zend_Controller_Response_Abstract|null $response
198 public function setResponse(
199 Zend_Controller_Response_Abstract $response = null
203 * Retrieve the response object, if any
205 * @return Zend_Controller_Response_Abstract|null
207 public function getResponse();
210 * Add a controller directory to the controller directory stack
212 * @param string $path
213 * @param string $args
214 * @return Zend_Controller_Dispatcher_Interface
216 public function addControllerDirectory($path, $args = null);
219 * Set the directory (or directories) where controller files are
222 * @param string|array $dir
223 * @return Zend_Controller_Dispatcher_Interface
225 public function setControllerDirectory($path);
228 * Return the currently set directory(ies) for controller file
233 public function getControllerDirectory();
236 * Dispatch a request to a (module/)controller/action.
238 * @param Zend_Controller_Request_Abstract $request
239 * @param Zend_Controller_Response_Abstract $response
240 * @return Zend_Controller_Request_Abstract|boolean
242 public function dispatch(
243 Zend_Controller_Request_Abstract $request,
244 Zend_Controller_Response_Abstract $response
248 * Whether or not a given module is valid
250 * @param string $module
253 public function isValidModule($module);
256 * Retrieve the default module name
260 public function getDefaultModule();
263 * Retrieve the default controller name
267 public function getDefaultControllerName();
270 * Retrieve the default action
274 public function getDefaultAction();
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.
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).