如何在多个类(和模块)上使用ZF2的EventManager?

时间:2013-05-01 13:41:05

标签: php zend-framework2

我有以下设置:在控制器中我触发一个事件,我想在其他地方附加多个侦听器。

目前,我的 onBootstrap

中有以下听众
$e->getApplication()->getServiceManager()->get('EventManager')->attach('*', function($e) {
    var_dump($e->getName());
});

以下代码作为工厂

'Application\Controller\Foo' => function(ControllerManager $cm) {
    $eventManager = $cm->getServiceLocator()->get('EventManager');
    $controller = new \Application\Controller\FooController();
    $controller->setEventManager($eventManager);
    return $controller;
},

最后我的控制器中的以下触发器:

$this->getEventManager()->trigger('foo-finished', 'finishedAction', array(
    'obj' => $foo->someObject()
));

所以它应该与我从服务定位器接收到的EventManager相同并将其注入控制器。我仍然没有输出。在附加到事件时我也尝试使用$e->getApplication()->getEventManager(),但这只给了我ZF内部事件。

我读到了SharedEventManager,但我不完全理解为什么要传递上下文。我这样尝试过(据我所知),但仍然没有输出。

$e->getApplication()->getServiceManager()->get('EventManager')
    ->getSharedManager()
    ->attach('finishedAction', '*', function() { ... });

那么,我做错了什么?我只是想触发事件并在可能不同的模块中捕获它们,但它似乎变得如此复杂......

2 个答案:

答案 0 :(得分:4)

默认情况下,EventManager服务未共享,这意味着每次调用$serviceLocator->get('EventManager')时都会获得不同的实例,这就是您应该使用SharedEventManager的原因 - 看一看在@Crisp的link看看如何使用它。

还有一个提示:不要尝试在对象中注入Mvc EventManager,每个对象都应该触发自己的事件。

答案 1 :(得分:0)

以下对我有用(不是getEventManager和getSharedManager的顺序),还要注意事件名称和上下文(或标识符)的顺序。

$e->getApplication()->getEventManager()->getSharedManager()->attach('*', 'finishedAction', function() { ... });

问候!