Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zend controller's predispatch method

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 ?

like image 465
Mouna Cheikhna Avatar asked Feb 17 '12 04:02

Mouna Cheikhna


3 Answers

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.

like image 101
drew010 Avatar answered Sep 27 '22 23:09

drew010


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.

like image 34
RockyFord Avatar answered Sep 27 '22 22:09

RockyFord


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.

like image 29
Tadas Sasnauskas Avatar answered Sep 28 '22 00:09

Tadas Sasnauskas