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

How to register event listeners for a controller in 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 的这个: 但我不确定如何适应 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());