如何在ZF2中触发附加到共享事件管理器的事件?

时间:2015-06-12 02:01:40

标签: events zend-framework2 eventtrigger event-listener

附加到(本地)事件管理器的事件

public class myClass implements EventManagerAwareInterface {
    ...
    public function __construct(...) {
        ...
        $this->getEventManager()->attach('doEvent', function ($e) {
            $event = $e->getName();
            $params = $e->getParams();
            printf(
                'Handled event "%s", with parameters %s',
                $event,
                json_encode($params)
            );
        });
    }
    ...
    public function getEventManager() {
        if (!$this->eventManager) {
            $this->setEventManager(new EventManager());
        }
        return $this->eventManager;
    }
    public function setEventManager(EventManagerInterface $eventManager) {
        $eventManager->setIdentifiers(array(
            __CLASS__,
            get_class($this),
            'exampleIdentifier',
        ));
        $this->eventManager = $eventManager;
        return $this;
    }
}

可以在本地触发,如下所示:

public class myClass {
    ...
    public function doWhatEver(...) {
        $this->getEventManager()->trigger('doEvent', null, ['foo' => 'bar', 'baz' => 'bat']);
    }
    ...
}

如果我正确理解共享事件管理器,它就是事件和侦听器的中央寄存器,捆绑到identifiers。每个(本地)事件管理器都知道它。 (顺便说一句:这个ZF2魔法是如何工作的?)每个事件管理员都可以访问1.在其中注册的监听器和2.到共享事件管理器的“池”。将事件附加到此池与附加到事件管理器的公共事件类似,但需要一个额外的参数 - identifier(共享“池”中“侦听器包”的键):

this->getEventManager()->getSharedManager()->attach('exampleIdentifier', 'doEvent', function ($e) {
    ...
});

来自同一类的触发完全相同:

$this->getEventManager()->trigger('doEvent', null, ['foo' => 'bar', 'baz' => 'bat']);

现在我想将触发器调用移动到另一个类。但我不明白,如何传递正确的identifier如何从类中触发附加到共享事件管理器的事件,该ServiceManager具有不同的identifier / identifier设置?

1 个答案:

答案 0 :(得分:4)

  

如何在ZF2中触发附加到共享事件管理器的事件?

尽管有名称,但SharedEventManager是not an event manager;因此它无法触发'事件

我们的想法是,您可以将事件侦听器附加到通常附加到服务(可以识别事件管理器)的共享事件管理器。

为什么要这么麻烦?

共享事件管理器提供以下好处。

  • 新事件监听器可以附加到可能存在或可能不存在的事件管理器

  • 通过使用'标识符'允许侦听器附加到可能来自不同来源的一组事件。

第二点是重要的一点。通过使用事件管理器'标识符'您可以将事件侦听器附加到多个事件管理器/服务。

考虑以下

use Zend\EventManager\EventManagerAwareTrait;
use Zend\EventManager\EventManagerAwareInterface;

abstract class AbstractService implements EventManagerAwareInterface
{
    use EventManagerAwareTrait;

    public function __construct()
    {
        $this->getEventManager()->addIdentifiers([
            'my_custom_identifier',
        ]);
    }

    public function doSomething()
    {
        $this->getEventManager()->trigger(__FUNCTION__, ['foo' => 'bar']);
    }
}

class ServiceA extends AbstractService
{}

class ServiceB extends AbstractService
{}

如果我们想要将监听器附加到' doSomething'而没有共享事件管理器。我们需要为每个活动经理这样做。

使用共享管理器,您可以在一次调用中同时定位,无需创建serviceAserviceB或复制事件侦听器。

use Zend\ModuleManager\Feature\BootstrapListenerInterface;
use Zend\Mvc\MvcEvent;

class Module implements BootstrapListenerInterface
{
    public function onBootstrap(MvcEvent $event)
    {
        $application = $event->getApplication();
        $sharedEventManager = $application->getEventManager()->getSharedManager();

        $sharedEventManager->attach(
            'my_custom_identifier',
            'doSomething',
            function($event) {
                // some work
            }
        );
    }
}