1

在实现一个新的 ZF2 应用程序时,我发现自己在 EventManager 上苦苦挣扎。在应用程序模块中,我创建了一个AuthenticationListener和一个NotifierListener. 第一个检查用户的正确身份验证,第二个显示发送给登录用户的自定义消息。

现在我正在创建一个新模块,用于分派要导出的 xml 文件。我想保留AuthenticationListener但分离NotifierListener以避免E_NOTIFY错误。问题是,在阅读了博客/源代码/文档(很差)并将我的头发拉出来之后,我无法理解如何分离上面提到的监听器。

应用模块.php

public function onBootstrap($e)
{
    $eventManager = $e->getApplication()->getEventManager();

    $authListener = new AuthenticationListener();
    $authListener->attach($eventManager);

    $notifyListener = new NotifyListener();
    $notifyListener->attach($eventManager);
}

新模块.php

public function onBootstrap($e)
{
    $eventManager = $e->getApplication()->getEventManager();

    // ... $eventmanager->detach('NotifyListener');
}
4

2 回答 2

3

答案是让你的听众成为服务

由于它不需要构造函数参数,因此它是可调用的,因此将其设置在 invokables 数组中

public function getServiceConfig()
{
    return array(
        'invokables' => array(
            'NotifyListener' => 'FQCN\To\NotifyListener',
        ),
    );
}

从服务管理器中获取它,而不是直接在引导程序中创建新实例

public function onBootstrap($e)
{
    $eventManager = $e->getApplication()->getEventManager();

    $sm = $e->getApplication()->getServiceManager();

    $notifyListener = $sm->get('NotifyListener')
    $notifyListener->attach($eventManager);
}

任何你想分离它的地方,你只需要能够访问 ServiceManager

 // in any ServiceLocator aware class
 $sm = $this->getServiceLocator();
 $eventManager = $sm->get('Application')->getEventManager();
 $notifyListener = $sm->get('NotifyListener');
 $notifyListener->detach($eventManager);
于 2013-03-27T20:27:40.430 回答
0

你走在正确的道路上。您唯一需要做的就是调用detach()您的NotifyListener而不是EvenManager. 下面的示例来自 Zend Framework 手册EventManager

链接: http: //framework.zend.com/manual/2.0/en/modules/zend.event-manager.event-manager.html#examples

use Zend\Cache\Cache;
use Zend\EventManager\EventCollection;
use Zend\EventManager\ListenerAggregateInterface;
use Zend\EventManager\EventInterface;

class CacheListener implements ListenerAggregateInterface
{
    protected $cache;

    protected $listeners = array();

    public function __construct(Cache $cache)
    {
        $this->cache = $cache;
    }

    public function attach(EventCollection $events)
    {
        $this->listeners[] = $events->attach('get.pre', array($this, 'load'), 100);
        $this->listeners[] = $events->attach('get.post', array($this, 'save'), -100);
    }

    public function detach(EventManagerInterface $events)
    {
        foreach ($this->listeners as $index => $listener) {
            if ($events->detach($listener)) {
                unset($this->listeners[$index]);
            }
        }
    }

    public function load(EventInterface $e)
    {
        // some code to load
    }

    public function save(EventInterface $e)
    {
        // some code to save 
    }
}

这个例子很好地说明了如何准备一个监听器(例如AuthenticationListener)实现ListenerAggregateInterface

Module假设与您的对象相同的情况:

public function onBootstrap($e)
{
    $eventManager = $e->getApplication()->getEventManager();
    $cacheListener = new CacheListener($cache);
    $cacheListener->detach($eventManager);
}

因此,假设您的NotifyListener实现ListenerAggregateInterface或只是有一个detach()方法,您可以编写onBootstrap()方法来分离侦听器,如下所示:

public function onBootstrap($e)
{
    $eventManager = $e->getApplication()->getEventManager();
    $notifyListener = new NotifyListener();
    $notifyListener->detach($eventManager);
}

希望这会有所帮助,反馈将不胜感激:)

斯托扬

于 2013-03-27T20:29:38.910 回答