Zend控制器的predispatch方法

时间:2012-02-17 04:56:52

标签: model-view-controller zend-framework controller request

我正在阅读this以了解zend的MVC请求生命周期。 但是我想不出zend中我会使用控制器的predispatch方法的任何情况,对于我想在控制器操作之前执行的代码,init方法不够。

控制器的predispatch应该是什么,而不是init。

你能举个例子吗?

3 个答案:

答案 0 :(得分:10)

请参阅Zend_Controller_Action - Object Initialization和以下Pre and Post Dispatch Hooks部分。他们都详细介绍了两者和动作控制器本身。

init()更多用于设置控制器对象并进行可用于所有操作的初始化。由于init()preDispatch()之前运行,因此您在init()中设置的任何内容都可供preDispatch()使用。虽然可以从init()转发或重定向,但最佳做法是从preDispatch()执行此操作,因为它在调度控制器操作之前运行。

从手册:

  

注意:init()与preDispatch()的使用它们之间有什么区别(init和preDispatch),你会采取什么行动?   在每个?

     

init()方法主要用于扩展   构造函数。通常,构造函数应该只设置对象   状态,而不是执行太多的逻辑。这可能包括初始化   控制器中使用的资源(例如模型,配置   对象等),或指定从前面检索的值   控制器,引导程序或注册表。

     

preDispatch()方法也可用于设置对象或   环境(例如,观点,行动助手等)状态,但它的主要   目的是决定是否要求采取行动   应该派遣。如果没有,那么你应该 _forward()来   另一个动作,或抛出异常。

     

注意: _forward() init()执行时实际上无法正常工作,这是意图的正式化   这两种方法。

答案 1 :(得分:2)

扩展drew010这里的答案是我如何使用preDispatch()和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');

    }

我使用preDispatch()来设置每个操作的布局,因为它不是默认布局,而在init()中我初始化我的flash messenger并为此控制器设置会话命名空间并将会话初始化为属性。

答案 2 :(得分:1)

这里有一个流行的问题,你可以使用init()而不是preDispatch()浪费大量资源:如果你使用控制器插件的preDispatch()方法进行访问控制,那么调用序列将是:YourController :: init(),YourAccessPlugin :: preDispatch(),YourController :: preDispatch(),YourController :: whateverAction。这意味着如果您在init()中执行任何繁重的工作,则未经授权的用户可以触发。比如说你在init()中启动一个新的会话命名空间然后无意识的搜索机器人可能会导致你的会话数据库充满空会话。因此,在init中坚持使用非常基本的简单内容,避免触及或修改任何资源,避免数据库访问。