1

新しい ZF2 アプリを実装すると、EventManager に苦労していることに気づきました。アプリケーション モジュールで と を作成しましAuthenticationListenerNotifierListener。1 つ目はユーザーの適切な認証をチェックし、2 つ目はログに記録されたユーザー宛てのカスタム メッセージを表示します。

現在、エクスポートする xml ファイルをディスパッチする新しいモジュールを作成しています。を保持したいのですが、エラーを避けるためAuthenticationListenerに を切り離します。問題は、ブログ/ソースコード/ドキュメント (かなり貧弱) を読んで髪を引っ張った後、上記のリスナーを切り離す方法を理解できないことです。NotifierListenerE_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()あなたに電話することだけです。以下の例は、 の Zend Framework マニュアルからのものです。NotifyListenerEvenManagerEventManager

リンク: 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 に答える