I was reading this to understand zend's MVC Request Lifecycle. But i can't think of any cases in zend where i would use a controller's predispatch method , isn't the init method enough for the code that i want executed before controller's actions .
What should exactly should be in a controller's predispatch and not init .
Can you give an example ?
See Zend_Controller_Action - Object Initialization and the following section Pre and Post Dispatch Hooks. They both go into some detail on the two, and the Action Controller itself.
init()
is more for setting up the controller object and doing initialization that will be available to all of your actions. Since init()
runs prior to preDispatch()
, anything you set up in init()
will be available for preDispatch()
to use. While it is possible to forward or redirect from init()
, it is best practice to do it from preDispatch()
because it runs prior to dispatching the controller action.
From the manual:
Note: Usage of init() vs. preDispatch() What is the difference between them (init and preDispatch), and what actions would you take in each?
The init() method is primarily intended for extending the constructor. Typically, your constructor should simply set object state, and not perform much logic. This might include initializing resources used in the controller (such as models, configuration objects, etc.), or assigning values retrieved from the front controller, bootstrap, or a registry.
The preDispatch() method can also be used to set object or environmental (e.g., view, action helper, etc.) state, but its primary purpose is to make decisions about whether or not the requested action should be dispatched. If not, you should then _forward() to another action, or throw an exception.
Note: _forward() actually will not work correctly when executed from init(), which is a formalization of the intentions of the two methods.
to extend drew010's answer here is an example of how I use preDispatch() and int():
public function preDispatch() {
$this->_helper->layout->setLayout('admin');
}
/**
*initiaize the flashmessenger and assign the _session property
*/
public function init() {
if ($this->_helper->FlashMessenger->hasMessages()) {
$this->view->messages = $this->_helper->FlashMessenger->getMessages();
}
//set the session namespace to property for easier access
$this->_session = new Zend_Session_Namespace('location');
}
I use preDispatch() to set the layout for every action as it not the default layout and in init() I initialize my flash messenger and setup the session namespace for this controller and initialize the session as a property.
Here's one popular gotcha where you can waste loads of resources using init() instead of preDispatch(): if you do access control using controller plugin's preDispatch() method then call sequence will be: YourController::init(), YourAccessPlugin::preDispatch(), YourController::preDispatch(), YourController::whateverAction. This means that if you do any heavy lifting in init() then unauthorized users can trigger it. Say for e.g. you start a new session namespace in init() then mindless search bots can cause your session database to be littered with empty sessions. So stick to very basic simple stuff in init, avoid touching or modifying any resources, avoid database access.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With