Overview<wbr></wbr>¶
Zend_Controller_Front<wbr></wbr>implementsa<wbr></wbr>»Front Controller pattern<wbr></wbr>usedin<wbr></wbr>»Model-View-Controller (MVC)<wbr></wbr>applications. Itspurpose is to initialize the request environment, route theincoming request, and then dispatch any discovered actions; itaggregates any responses and returns them when the process iscomplete.
Zend_Controller_Front<wbr></wbr>also implementsthe<wbr></wbr>»Singleton pattern, meaning only a single instance of it may beavailable at any given time. This allows it to also act as aregistry on which the other objects in the dispatch process maydraw.
Zend_Controller_Front<wbr></wbr>registersa<wbr></wbr>pluginbroker<wbr></wbr>with itself,allowing various events it triggers to be observed by plugins. Inmost cases, this gives the developer the opportunity to tailor thedispatch process to the site without the need to extend the frontcontroller to add functionality.
At a bare minimum, the front controller needs one or more paths todirectories containing<wbr></wbr>actioncontrollers<wbr></wbr>in order to do itswork. A variety of methods may also be invoked to further tailorthe front controller environment and that of its helperclasses.
Note:<wbr></wbr>Default Behaviour
By default, the frontcontroller loads the<wbr></wbr>ErrorHandler<wbr></wbr>plugin,as well as the<wbr></wbr>ViewRenderer<wbr></wbr>actionhelper plugin. These are to simplify error handling and viewrenderering in your controllers, respectively.<wbr></wbr>
To disable the<wbr></wbr>ErrorHandler, perform the following at any pointprior to calling<wbr></wbr>dispatch():<wbr></wbr>To disable the <wbr></wbr> ViewRenderer, do the following prior tocalling <wbr></wbr> dispatch(): <wbr></wbr>
//Disable the ErrorHandler plugin: $front-> setParam ( 'noErrorHandler', <wbr></wbr> true );
//Disable the ViewRenderer helper: $front-> setParam ( 'noViewRenderer', <wbr></wbr> true );
Primary Methods<wbr></wbr>¶
The front controller has several accessors for setting up itsenvironment. However, there are three primary methods key to thefront controller's functionality:
getInstance()<wbr></wbr>¶
getInstance()<wbr></wbr>is used toretrieve a front controller instance. As the front controllerimplements a Singleton pattern, this is also the only meanspossible for instantiating a front controller object.
-
$front <wbr></wbr>=Zend_Controller_Front:: getInstance ( );
setControllerDirectory() and addControllerDirectory<wbr></wbr>¶
setControllerDirectory()<wbr></wbr>is used totell<wbr></wbr>thedispatcher<wbr></wbr>where to lookfor<wbr></wbr>actioncontroller<wbr></wbr>class files. Itaccepts either a single path or an associative array of module andpath pairs.
As some examples:
-
// Setthe default controller directory:
-
$front-> setControllerDirectory ( '../application/controllers' );
-
<wbr></wbr>
-
// Setseveral module directories at once:
-
<wbr><wbr><span><wbr></wbr></span><span style="color:rgb(255,0,0)">'default'</span><span><wbr></wbr></span>=><span><wbr></wbr></span><span style="color:rgb(255,0,0)">'../application/controllers'</span>,</wbr></wbr>
-
<wbr><wbr><span><wbr></wbr></span><span style="color:rgb(255,0,0)">'blog'</span><wbr><wbr> =><span><wbr></wbr></span><span style="color:rgb(255,0,0)">'../modules/blog/controllers'</span>,</wbr></wbr></wbr></wbr>
-
<wbr><wbr><span><wbr></wbr></span><span style="color:rgb(255,0,0)">'news'</span><wbr><wbr> =><span><wbr></wbr></span><span style="color:rgb(255,0,0)">'../modules/news/controllers'</span>,</wbr></wbr></wbr></wbr>
-
) );
-
<wbr></wbr>
-
// Adda 'foo' module directory:
-
$front-> addControllerDirectory ( '../modules/foo/controllers', <wbr></wbr> 'foo' );
Note: If you use<wbr></wbr>addControllerDirectory()<wbr></wbr>withouta module name, it will set the directory for the<wbr></wbr>default<wbr></wbr>module --overwriting it if it already exists.<wbr></wbr>
You can get the current settings for the controller directoryusing<wbr></wbr>getControllerDirectory();this will return an array of module and directory pairs.
addModuleDirectory() and getModuleDirectory()<wbr></wbr>¶
One aspect of the front controller is that you may<wbr></wbr>definea modular directory structure<wbr></wbr>for creatingstandalone components; these are called "modules".
Each module should be in its own directory and mirror the directorystructure of the default module -- i.e., it should havea<wbr></wbr>/controllers/<wbr></wbr>subdirectory atthe minimum, and typically a<wbr></wbr>/views/<wbr></wbr>subdirectory andother application subdirectories.
addModuleDirectory()<wbr></wbr>allows you to passthe name of a directory containing one or more module directories.It then scans it and adds them as controller directories to thefront controller.
Later, if you want to determine the path to a particular module orthe current module, you can callgetModuleDirectory(),optionally passing a module name to get that specific moduledirectory.
dispatch()<wbr></wbr>¶
dispatch(Zend_Controller_Request_Abstract $request = null,Zend_Controller_Response_Abstract $response =null)<wbr></wbr>does the heavywork of the front controller. It may optionally take a<wbr></wbr>requestobject<wbr></wbr>and/ora<wbr></wbr>responseobject, allowing the developer to pass in custom objects foreach.
If no request or response object are passed in,<wbr></wbr>dispatch()<wbr></wbr>willcheck for previously registered objects and use those orinstantiate default versions to use in its process (in both cases,the<wbr></wbr>HTTPflavor will be used as the default).
Similarly,<wbr></wbr>dispatch()<wbr></wbr>checksfor registered<wbr></wbr>router<wbr></wbr>and<wbr></wbr>dispatcher<wbr></wbr>objects,instantiating the default versions of each if none is found.
The dispatch process has three distinct events:
-
Routing
-
Dispatching
-
Response
Routing takes place exactly once, using the values in the requestobject when<wbr></wbr>dispatch()<wbr></wbr>iscalled. Dispatching takes place in a loop; a request may eitherindicate multiple actions to dispatch, or the controller or aplugin may reset the request object to force additional actions todispatch. When all is done, the front controller returns aresponse.
run()<wbr></wbr>¶
Zend_Controller_Front::run($path)<wbr></wbr>is a static methodtaking simply a path to a directory containing controllers. Itfetches a front controller instance (via<wbr></wbr>getInstance(),registers the path provided via<wbr></wbr>setControllerDirectory(),and finally<wbr></wbr>dispatches.
Basically,<wbr></wbr>run()<wbr></wbr>isa convenience method that can be used for site setups that do notrequire customization of the front controller environment.
-
//Instantiate front controller, set controller directory, anddispatch in one
-
//easy step:
-
Zend_Controller_Front:: run ( '../application/controllers' );
Environmental Accessor Methods<wbr></wbr>¶
In addition to the methods listed above, there are a number ofaccessor methods that can be used to affect the front controllerenvironment -- and thus the environment of the classes to which thefront controller delegates.
-
resetInstance()<wbr></wbr>can be used toclear all current settings. Its primary purpose is for testing, butit can also be used for instances where you wish to chain togethermultiple front controllers.
-
setDefaultControllerName<wbr>()</wbr><wbr></wbr>and<wbr></wbr>getDefaultControllerName<wbr>()</wbr><wbr></wbr>letyou specify a different name to use for the default controller('index' is used otherwise) and retrieve the current value. Theyproxy to<wbr></wbr>thedispatcher.
-
setDefaultAction()<wbr></wbr>and<wbr></wbr>getDefaultAction()<wbr></wbr>letyou specify a different name to use for the default action ('index'is used otherwise) and retrieve the current value. They proxyto<wbr></wbr>thedispatcher.
-
setRequest()<wbr></wbr>and<wbr></wbr>getRequest()<wbr></wbr>letyou specify<wbr></wbr>therequest<wbr></wbr>class or object touse during the dispatch process and to retrieve the current object.When setting the request object, you may pass in a request classname, in which case the method will load the class file andinstantiate it.
-
setRouter()<wbr></wbr>getRouter()<wbr></wbr>letyou specify<wbr></wbr>therouter<wbr></wbr>class or object touse during the dispatch process and to retrieve the current object.When setting the router object, you may pass in a router classname, in which case the method will load the class file andinstantiate it.
When retrieving the router object, it first checks to see if one ispresent, and if not, instantiates the default router (rewriterouter).
-
setBaseUrl()<wbr></wbr>and<wbr></wbr>getBaseUrl()<wbr></wbr>letyou specify<wbr></wbr>thebase<wbr></wbr>URL<wbr></wbr>to strip whenrouting requests and to retrieve the current value. The value isprovided to the request object just prior to routing.
-
setDispatcher()<wbr></wbr>and<wbr></wbr>getDispatcher()<wbr></wbr>letyou specify<wbr></wbr>thedispatcher<wbr></wbr>class or object touse during the dispatch process and retrieve the current object.When setting the dispatcher object, you may pass in a dispatcherclass name, in which case the method will load the class file andinstantiate it.
When retrieving the dispatcher object, it first checks to see ifone is present, and if not, instantiates the defaultdispatcher.
-
setResponse()<wbr></wbr>and<wbr></wbr>getResponse()<wbr></wbr>letyou specify<wbr></wbr>theresponse<wbr></wbr>class or object touse during the dispatch process and to retrieve the current object.When setting the response object, you may pass in a response classname, in which case the method will load the class file andinstantiate it.
-
registerPlugin(Zend_Controller_Plugin_Abstract $plugin, $stackIndex= null)allows you to register<wbr></wbr>pluginobjects. By setting the optional<wbr></wbr>$stackIndex,you can control the order in which plugins will execute.
-
unregisterPlugin($plugin)<wbr></wbr>let youunregister<wbr></wbr>pluginobjects.<wbr></wbr>$plugin<wbr></wbr>maybe either a plugin object or a string denoting the class of pluginto unregister.
-
throwExceptions($flag)<wbr></wbr>is used to turnon/off the ability to throw exceptions during the dispatch process.By default, exceptions are caught and placed in the<wbr></wbr>responseobject; turning onthrowExceptions()<wbr></wbr>willoverride this behaviour.
For more information, read<wbr></wbr>MVCExceptions.
-
returnResponse($flag)<wbr></wbr>is used to tellthe front controller whether to return the response(TRUE) from<wbr></wbr>dispatch(),or if the response should be automatically emitted(FALSE). By default, the response is automaticallyemitted (by callingZend_Controller_Response_Abstract::sendResponse());turning on<wbr></wbr>returnResponse()<wbr></wbr>willoverride this behaviour.
Reasons to return the response include a desire to check forexceptions prior to emitting the response, needing to log variousaspects of the response (such as headers), etc.
Front Controller Parameters<wbr></wbr>¶
In the introduction, we indicated that the front controller alsoacts as a registry for the various controller components. It doesso through a family of "param" methods. These methods allow you toregister arbitrary data -- objects and variables -- with the frontcontroller to be retrieved at any time in the dispatch chain. Thesevalues are passed on to the router, dispatcher, and actioncontrollers. The methods include:
-
setParam($name, $value)<wbr></wbr>allows you to seta single parameter of<wbr></wbr>$name<wbr></wbr>withvalue<wbr></wbr>$value.
-
setParams(array $params)<wbr></wbr>allows you to setmultiple parameters at once using an associative array.
-
getParam($name)<wbr></wbr>allows you toretrieve a single parameter at a time, using<wbr></wbr>$name<wbr></wbr>asthe identifier.
-
getParams()<wbr></wbr>allows you toretrieve the entire list of parameters at once.
-
clearParams()<wbr></wbr>allows you toclear a single parameter (by passing a string identifier), multiplenamed parameters (by passing an array of string identifiers), orthe entire parameter stack (by passing nothing).
There are several pre-defined parameters that may be set that havespecific uses in the dispatch chain:
-
useDefaultControllerAlwa<wbr>ys</wbr><wbr></wbr>is used to hintto<wbr></wbr>thedispatcher<wbr></wbr>to use the defaultcontroller in the default module for any request that is notdispatchable (i.e., the module, controller, and/or action do notexist). By default, this is off.
See<wbr></wbr>MVCExceptions You May Encounter<wbr></wbr>for more detailedinformation on using this setting.
-
disableOutputBuffering<wbr></wbr>is used to hintto<wbr></wbr>thedispatcher<wbr></wbr>that it should notuse output buffering to capture output generated by actioncontrollers. By default, the dispatcher captures any output andappends it to the response object body content.
-
noViewRenderer<wbr></wbr>is used to disablethe<wbr></wbr>ViewRenderer.Set this parameter to<wbr></wbr>TRUE<wbr></wbr>todisable it.
-
noErrorHandler<wbr></wbr>is used to disablethe<wbr></wbr>ErrorHandler plugin. Set this parameter to<wbr></wbr>TRUE<wbr></wbr>todisable it.
Extending the Front Controller<wbr></wbr>¶
To extend the Front Controller, at the very minimum you will needto override the<wbr></wbr>getInstance()method:
-
class <wbr></wbr>My_Controller_Front <wbr></wbr> extends <wbr></wbr>Zend_Controller_Front
-
{
-
<wbr><wbr><span><wbr></wbr></span><span style="color:rgb(0,0,0)"><strong>public</strong></span><span><wbr></wbr></span><a href="http://www.php.net/static"><span style="color:rgb(0,0,102)">static</span></a><span><wbr></wbr></span><span style="color:rgb(0,0,0)"><strong>function</strong></span><span><wbr></wbr></span>getInstance<span style="color:rgb(102,204,102)">(</span><span style="color:rgb(102,204,102)">)</span></wbr></wbr>
-
<wbr><wbr><span><wbr></wbr></span><span style="color:rgb(102,204,102)">{</span></wbr></wbr>
-
<wbr><wbr><wbr><wbr><span><wbr></wbr></span><span style="color:rgb(177,177,0)">if</span><span><wbr></wbr></span><span style="color:rgb(102,204,102)">(</span><span style="color:rgb(0,0,0)"><strong>null</strong></span><span><wbr></wbr></span>===self::<span style="color:rgb(0,0,255)">$_instance</span><span style="color:rgb(102,204,102)">)</span><span><wbr></wbr></span><span style="color:rgb(102,204,102)">{</span></wbr></wbr></wbr></wbr>
-
<wbr><wbr><wbr><wbr><wbr><wbr>self::<span style="color:rgb(0,0,255)">$_instance</span><span><wbr></wbr></span>=<span><wbr></wbr></span><span style="color:rgb(0,0,0)"><strong>new</strong></span><span><wbr></wbr></span>self<span style="color:rgb(102,204,102)">(</span><span style="color:rgb(102,204,102)">)</span>;</wbr></wbr></wbr></wbr></wbr></wbr>
-
<wbr><wbr><wbr><wbr><span><wbr></wbr></span><span style="color:rgb(102,204,102)">}</span></wbr></wbr></wbr></wbr>
-
<wbr></wbr>
-
<wbr><wbr><wbr><wbr><span><wbr></wbr></span><span style="color:rgb(177,177,0)">return</span><span><wbr></wbr></span>self::<span style="color:rgb(0,0,255)">$_instance</span>;</wbr></wbr></wbr></wbr>
-
<wbr><wbr><span><wbr></wbr></span><span style="color:rgb(102,204,102)">}</span></wbr></wbr>
-
}
Overriding the<wbr></wbr>getInstance()<wbr></wbr>methodensures that subsequent calls toZend_Controller_Front::getInstance()<wbr></wbr>willreturn an instance of your new subclass instead of aZend_Controller_Front<wbr></wbr>instance-- this is particularly useful for some of the alternate routersand view helpers.
Typically, you will not need to subclass the front controllerunless you need to add new functionality (for instance, a pluginautoloader, or a way to specify action helper paths). Some pointswhere you may want to alter behaviour may include modifying howcontroller directories are stored, or what default router ordispatcher are used.