How to trigger an event attached to the Shared Event Manager in ZF2?

会有一股神秘感。 提交于 2019-12-23 15:39:26

问题


An event attached to a (local) event manager

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;
    }
}

can be triggered locally as follows:

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

If I understand the Shared Event Manager correctly, it's a central register of events and listeners, bundled to identifiers. It is known by every (local) event manager. (Btw.: How does this ZF2 magic work?) Every event manager has access 1. to the listeners registered in it and 2. to the shared event manager's "pool". Attaching an event to this pool is similar to the common event attaching to an event manager, but requires an additional parameter -- identifier (the key of the "listeners bundle" in the shared "pool"):

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

The triggering from the same class is exactly identical:

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

Now I want to move the trigger-call to another class. But I don't understand, how to pass the correct identifier. How to trigger an event attached to the Shared Event Manager from a class, that has a ServiceManager with a different identifier / identifiers set?


回答1:


How to trigger an event attached to the Shared Event Manager in ZF2?

Despite the name, the SharedEventManager is not an event manager; therefore it cannot 'trigger' events.

The idea is that you can attach event listener(s) to the shared event manager that would normally be attached to a service (which is event manager aware).

Why bother?

The shared event manager provides the following benefits.

  • The new event listeners can be attached to event managers that may or may not exist yet

  • Allows listeners to be attached to a set of events that may come from different sources, by using 'identifiers'.

The second point is the important one. By using a event manager 'identifier' you are able to attach event listeners to more than one event manager/service.

Consider the following

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
{}

Without the shared event manager if we wanted to attach a listener to the 'doSomething' event we would need to do so for each event manager.

With the shared manager you can target both in one call, without needing to create serviceA or serviceB or duplicate the event listener.

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
            }
        );
    }
}


来源:https://stackoverflow.com/questions/30794259/how-to-trigger-an-event-attached-to-the-shared-event-manager-in-zf2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!