【问题标题】:Zend controller's predispatch methodZend 控制器的 predispatch 方法
【发布时间】:2012-03-08 13:12:15
【问题描述】:

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

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

你能举个例子吗?

【问题讨论】:

  • 自从我编写 Zend 应用程序以来已经很久很久了(因此这是评论而不是答案),但首先想到的是如果您有一个身份验证助手正在确保用户有权访问控制器。

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


【解决方案1】:

请参阅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() 执行时实际上不会正常工作,这是意图的形式化 两种方法中的一种。

【讨论】:

    【解决方案2】:

    在这里扩展draw010的答案是我如何使用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 并为此控制器设置会话命名空间并将会话初始化为属性。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-29
        • 2014-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多