如何在 Cakephp2 中为控制器注册事件监听器?

问题描述

我想在 cakePHP2.10 中从我的控制器分派一个事件。因此我需要为控制器注册事件监听器。当事件从我的模型发出时,实现这一点很简单,但我无法为我的控制器弄清楚。从书中:https://book.cakephp.org/2/en/core-libraries/events.html#global-event-manager

App::uses('ClassRegistry','Utility');
App::uses('UserEventsListener','Lib/Event');
$User = ClassRegistry::init('User');
$User->getEventManager()->attach(new UserEventsListener());

控制器会是这样吗,还是我只能对控制器发出的事件使用全局事件?

App::uses('TestController','Controller');
$test = new TestController();
$test->getEventManager()->attach(new TestEventsListener());

我也为 cakePHP3 看到了这个:CakePHP 3 Controller Event Implementation Example 但我不确定如何为 cakePHP2.x 调整它。谢谢

解决方法

您永远不应该手动实例化控制器(可能在单元测试中除外),如果您觉得有必要这样做,那么这表明您的应用程序架构中可能存在缺陷。

与模型不同,每个请求只能涉及一个控制器(如果有多个,这将再次表明存在架构缺陷),因此理想情况下,您没有理由将侦听器附加到特定的控制器实例.

我想说的是,如果您有多个控制器来调度该事件,但您只想听其中一个,那么这又是一个可能的架构缺陷,很可能可以通过以下方式解决在该特定控制器中正确确定事件范围,例如使用像 Controller.Test.myEvent 这样的特定控制器名称。在您的听众中,您还可以检查主题是否是特定实例,但如果听众需要了解有关主题的那么多,那么这可能不太好。

说了这么多,是的,请改用全局事件管理器,它与链接答案中的原理相同,例如:

// In app/Lib/Event/TestEventsListener.php
App::uses('CakeEventListener','Event');

class TestEventsListener implements CakeEventListener {

    public function implementedEvents() {
        return array(
            'Controller.Test.myEvent' => 'testScopedMyEvent',);
    }

    public function myEvent($event) {
        // testScopedMyEvent happend,do something...
    }
}

然后在您的控制器中相应地分派您的事件:

$event = new CakeEvent('Controller.Test.myEvent',$this,array(
    'some' => $eventData
));
$this->getEventManager()->dispatch($event);

另见

,

这是我的错误。我试图实例化控制器以附加侦听器,但我应该这样做:

CakeEventManager::instance()->attach(new TestListener());

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...