我只是设置一个侦听器聚合类来响应某些事件。我希望能够灵活变通,并且可以通过配置文件轻松打开和关闭监听器。
ListenerAggregate看起来像这样(简化):
LogEventsListener.php:
namespace MyApp\Listener;
class LogEventsListener implements ListenerAggregateInterface
{
/**
* @var \Zend\Stdlib\CallbackHandler[]
*/
protected $listeners = array();
/**
* {@inheritDoc}
*/
public function attach(EventManagerInterface $events)
{
$sharedEvents = $events->getSharedManager();
$this->listeners[] = $sharedEvents->attach(
'Zend\Mvc\Controller\AbstractActionController',
'runtime_error',
array($this, 'onLog'),
100
);
}
public function detach(EventManagerInterface $events)
{
foreach ($this->listeners as $index => $listener)
{
if ($events->detach($listener))
{
unset($this->listeners[$index]);
}
}
}
public function onLog(EventInterface $e)
{
// ... logging code ...
}
}
在application.config.php中我添加了侦听器数组,允许我关闭和打开侦听器,因为在这个应用程序中会有更多的侦听器聚合:
application.config.php:
return array(
'listeners' => array(
'MyApp\Listener\LogEventsListener',
// ... other listeners to follow ...
),
// ... other stuff ...
在我的主应用程序模块的module.config.php中,我添加了一个service_manager条目,以允许实例化侦听器聚合:
module.config.php:
'service_manager' => array(
'invokables' => array(
'MyApp\Listener\LogEventsListener' => 'MyApp\Listener\LogEventsListener',
),
// ... other stuff...
现在在我的应用程序模块的Module.php onBootstrap方法中,我想加载并附加监听器。有点像这样: Module.php:
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$sm = $e->getApplication()->getServiceManager();
$config = $sm->get('config');
if (array_key_exists('listeners', $config))
{
$listeners = $config['listeners'];
foreach ($userListeners as $curListener)
{
$listener = $sm->get($curListener);
$eventManager->attach($listener);
}
}
}
除了我注意到每次触发事件时都调用了两次事件处理程序(onLog)之外,这一切都很好用而且花花公子。
进一步的调查表明,显然是“听众”。 application.config.php中的数组正在被框架使用,因为它们的侦听器会自动被实例化并附加。因此,当我从Module.php中省略代码以手动附加侦听器时,它们仍然被附加。
我在官方文档中找不到有关此行为的任何内容,我不确定我是否可以依赖此行为。听众是否是'键入ZF2使用的特殊密钥,是否有更多关于此的信息?我可以依赖这样一个事实:在将来的版本中,框架中的侦听器将被加载吗?