Zend framework2 使用';时自动附加侦听器;听众';配置键

Zend framework2 使用';时自动附加侦听器;听众';配置键,zend-framework2,Zend Framework2,我刚刚建立了一个侦听器聚合类来响应某些事件。我想变得灵活,让自己能够通过配置文件轻松地关闭和打开侦听器 ListenerAggregate如下所示(简化): LogEventsListener.php: namespace MyApp\Listener; class LogEventsListener implements ListenerAggregateInterface { /** * @var \Zend\Stdlib\CallbackHandler[] *

我刚刚建立了一个侦听器聚合类来响应某些事件。我想变得灵活,让自己能够通过配置文件轻松地关闭和打开侦听器

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 ...
'service_manager' => array(
        'invokables' => array(
            'MyApp\Listener\LogEventsListener' => 'MyApp\Listener\LogEventsListener',
        ),
// ... other stuff...
在主应用程序模块的module.config.php中,我添加了一个service_manager条目,以允许实例化侦听器聚合:

module.config.php:

return array(
    'listeners' => array(
        'MyApp\Listener\LogEventsListener',
        // ... other listeners to follow ...
    ),
// ... other stuff ...
'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中的“listeners”数组显然正在被框架使用,因为它们的侦听器是自动实例化和附加的。因此,当我省略Module.php中手动附加侦听器的代码时,它们仍然被附加


我在官方文件中找不到关于这种行为的任何信息,我也不确定我是否可以依赖它。“监听器”键是ZF2使用的特殊键吗?是否有关于此的更多信息?我可以相信,在未来版本中,该阵列中的侦听器将由框架加载吗?

为什么不能?配置。谢谢@AlexP。文档中没有提到它仍然很奇怪,因为它实际上是一个非常有用的功能。对于这样的自定义侦听器,我建议您不要通过
application.config.php
加载,而是通过任何“普通”的
module.config.php
加载。您的侦听器可能不是特定于应用程序的,而是特定于模块的。此外,我建议您使用
SharedListenerAggregateInterface
,这样您就不需要手动调用
$em->getSharedManager()
。谢谢您的提示@JurianSluiman。那么您是如何解决的呢?使用
listeners
作为
module.config.php
中的键会导致侦听器被调用3次