Zend Front Controller

来源:互联网 发布:wish for mac 编辑:程序博客网 时间:2024/05/22 07:30

Overview 

Zend_Controller_Front implementsa »Front Controller pattern usedin »Model-View-Controller (MVC) 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 also implementsthe »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 registersa pluginbroker 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 actioncontrollers 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: Default Behaviour
By default, the frontcontroller loads the ErrorHandler plugin,as well as the ViewRenderer actionhelper plugin. These are to simplify error handling and viewrenderering in your controllers, respectively. 
To disable the ErrorHandler, perform the following at any pointprior to calling dispatch(): 

  1. //Disable the ErrorHandler plugin:
  2. $front->setParam('noErrorHandler', true);
To disable the ViewRenderer, do the following prior tocalling dispatch(): 
  1. //Disable the ViewRenderer helper:
  2. $front->setParam('noViewRenderer', true);

Primary Methods 

The front controller has several accessors for setting up itsenvironment. However, there are three primary methods key to thefront controller's functionality:

getInstance() 

getInstance() 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.

  1. $front =Zend_Controller_Front::getInstance();

setControllerDirectory() and addControllerDirectory 

setControllerDirectory() is used totell thedispatcher where to lookfor actioncontroller class files. Itaccepts either a single path or an associative array of module andpath pairs.

As some examples:

  1. // Setthe default controller directory:
  2. $front->setControllerDirectory('../application/controllers');
  3.  
  4. // Setseveral module directories at once:
  5. $front->setControllerDirectory(array(
  6.     'default' => '../application/controllers',
  7.     'blog'   => '../modules/blog/controllers',
  8.     'news'   => '../modules/news/controllers',
  9. ));
  10.  
  11. // Adda 'foo' module directory:
  12. $front->addControllerDirectory('../modules/foo/controllers', 'foo');

Note: If you use addControllerDirectory() withouta module name, it will set the directory for the default module --overwriting it if it already exists. 

You can get the current settings for the controller directoryusing getControllerDirectory();this will return an array of module and directory pairs.

addModuleDirectory() and getModuleDirectory() 

One aspect of the front controller is that you may definea modular directory structure 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 /controllers/ subdirectory atthe minimum, and typically a /views/ subdirectory andother application subdirectories.

addModuleDirectory() 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() 

dispatch(Zend_Controller_Request_Abstract $request = null,Zend_Controller_Response_Abstract $response =null) does the heavywork of the front controller. It may optionally take a requestobject and/ora responseobject, allowing the developer to pass in custom objects foreach.

If no request or response object are passed in, dispatch() willcheck for previously registered objects and use those orinstantiate default versions to use in its process (in both cases,the HTTPflavor will be used as the default).

Similarly, dispatch() checksfor registered router and dispatcher 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 dispatch() 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() 

Zend_Controller_Front::run($path) is a static methodtaking simply a path to a directory containing controllers. Itfetches a front controller instance (via getInstance(),registers the path provided via setControllerDirectory(),and finally dispatches.

Basically, run() isa convenience method that can be used for site setups that do notrequire customization of the front controller environment.

  1. //Instantiate front controller, set controller directory, anddispatch in one
  2. //easy step:
  3. Zend_Controller_Front::run('../application/controllers');

Environmental Accessor Methods 

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() 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() and getDefaultControllerName() letyou specify a different name to use for the default controller('index' is used otherwise) and retrieve the current value. Theyproxy to thedispatcher.

  • setDefaultAction() and getDefaultAction() letyou specify a different name to use for the default action ('index'is used otherwise) and retrieve the current value. They proxyto thedispatcher.

  • setRequest() and getRequest() letyou specify therequest 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() getRouter() letyou specify therouter 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() and getBaseUrl() letyou specify thebase URL to strip whenrouting requests and to retrieve the current value. The value isprovided to the request object just prior to routing.

  • setDispatcher() and getDispatcher() letyou specify thedispatcher 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() and getResponse() letyou specify theresponse 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 pluginobjects. By setting the optional $stackIndex,you can control the order in which plugins will execute.

  • unregisterPlugin($plugin) let youunregister pluginobjects. $plugin maybe either a plugin object or a string denoting the class of pluginto unregister.

  • throwExceptions($flag) is used to turnon/off the ability to throw exceptions during the dispatch process.By default, exceptions are caught and placed in the responseobject; turning onthrowExceptions() willoverride this behaviour.

    For more information, read MVCExceptions.

  • returnResponse($flag) is used to tellthe front controller whether to return the response(TRUE) from dispatch(),or if the response should be automatically emitted(FALSE). By default, the response is automaticallyemitted (by callingZend_Controller_Response_Abstract::sendResponse());turning on returnResponse() 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 

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) allows you to seta single parameter of $name withvalue $value.

  • setParams(array $params) allows you to setmultiple parameters at once using an associative array.

  • getParam($name) allows you toretrieve a single parameter at a time, using $name asthe identifier.

  • getParams() allows you toretrieve the entire list of parameters at once.

  • clearParams() 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:

  • useDefaultControllerAlways is used to hintto thedispatcher 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 MVCExceptions You May Encounter for more detailedinformation on using this setting.

  • disableOutputBuffering is used to hintto thedispatcher 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 is used to disablethe ViewRenderer.Set this parameter to TRUE todisable it.

  • noErrorHandler is used to disablethe ErrorHandler plugin. Set this parameter to TRUE todisable it.

Extending the Front Controller 

To extend the Front Controller, at the very minimum you will needto override the getInstance()method:

  1. class My_Controller_Front extends Zend_Controller_Front
  2. {
  3.     public static function getInstance()
  4.     {
  5.        if (null ===self::$_instance) {
  6.           self::$_instance = new self();
  7.        }
  8.  
  9.        return self::$_instance;
  10.     }
  11. }

Overriding the getInstance() methodensures that subsequent calls toZend_Controller_Front::getInstance() willreturn an instance of your new subclass instead of aZend_Controller_Front 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.