如何为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: cakephp3控制器事件实现示例,但我不确定如何适应cakephp2.x。由于

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

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

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

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

我想说的是,如果你有多个控制器调度该事件,但你只想听其中一个,那么这又是一个可能的架构缺陷,这很可能通过在特定控制器中适当地确定事件范围来解决,例如使用特定的控制器名称,如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);

参见

  • 食谱比;核心库>通用>事件系统>注册监听器
  • 食谱比;核心库>通用>事件系统>注册全局监听器

最新更新