Quick Start
Typically, you will compose an EventManager
instance in a class.
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\EventManager;
use Zend\EventManager\EventManagerAwareInterface;
class Foo implements EventManagerAwareInterface
{
protected $events;
public function setEventManager(EventManagerInterface $events)
{
$events->setIdentifiers([
__CLASS__,
get_called_class(),
]);
$this->events = $events;
return $this;
}
public function getEventManager()
{
if (null === $this->events) {
$this->setEventManager(new EventManager());
}
return $this->events;
}
}
The above allows users to access the EventManager
instance, or reset it with a
new instance; if one does not exist, it will be lazily instantiated on-demand.
The instance property $events
is a convention for referring to the
EventManager instance.
An EventManager
is really only interesting if it triggers some events.
Basic triggering via the trigger()
method takes three arguments:
- The event name, which is usually the current function/method name;
- The target, which is usually the current object instance;
- Event arguments, which are usually the arguments provided to the current function/method.
class Foo
{
// ... assume events definition from above
public function bar($baz, $bat = null)
{
$params = compact('baz', 'bat');
$this->getEventManager()->trigger(__FUNCTION__, $this, $params);
}
}
In turn, triggering events is only interesting if something is listening for the event.
Listeners attach to the EventManager
, specifying a named event and the
callback to notify. The callback receives an Event
object, which has accessors
for retrieving the event name, target, and parameters. Let's add a listener, and
trigger the event.
use Zend\Log\Factory as LogFactory;
$log = LogFactory($someConfig);
$foo = new Foo();
$foo->getEventManager()->attach('bar', function ($e) use ($log) {
$event = $e->getName();
$target = get_class($e->getTarget());
$params = json_encode($e->getParams());
$log->info(sprintf(
'%s called on %s, using params %s',
$event,
$target,
$params
));
});
// The following method call:
$foo->bar('baz', 'bat');
// Results in the log message reading:
// bar called on Foo, using params {"baz" : "baz", "bat" : "bat"}"
Note that the second argument to attach()
is any valid PHP callable; an
anonymous function is shown in the example in order to keep the example
self-contained.
However, you could also utilize a valid function name, a functor, a string referencing a static method, or an array callback with a named static method or instance method. Again, any PHP callable is valid.
Sometimes you may want to specify listeners without yet having an object
instance of the class composing an EventManager
. Zend Framework enables this
through the concept of a SharedEventManager
.
Simply put, you can inject individual EventManager
instances with a well-known
SharedEventManager
, and the EventManager
instance will query it for
additional listeners.
Listeners attach to a SharedEventManager
in roughly the same way they do to
normal event managers; the call to attach
is identical to the EventManager
,
but expects an additional parameter at the beginning: a named instance.
Remember the example of composing an EventManager
, how we passed it an array
containing __CLASS__
and get_called_class()
? Those values are then used to
identify the event manager instance, and pull listeners registered with one of
those identifiers from the SharedEventManager
.
As an example, assuming we have a SharedEventManager
instance that we know has
been injected in our EventManager
instances (for instance, via dependency
injection), we could change the above example to attach via the shared
collection:
use Zend\Log\Factory as LogFactory;
// Assume $sharedEvents is a Zend\EventManager\SharedEventManager instance
$log = LogFactory($someConfig);
$sharedEvents->attach('Foo', 'bar', function ($e) use ($log) {
$event = $e->getName();
$target = get_class($e->getTarget());
$params = json_encode($e->getParams());
$log->info(sprintf(
'%s called on %s, using params %s',
$event,
$target,
$params
));
});
// Later, instantiate Foo:
$foo = new Foo();
$foo->setEventManager(new EventManager($sharedEvents, []));
// And we can still trigger the above event:
$foo->bar('baz', 'bat');
// results in log message:
// bar called on Foo, using params {"baz" : "baz", "bat" : "bat"}"
The EventManager
also provides the ability to detach listeners, short-circuit
execution of an event either from within a listener or by testing return values
of listeners, test and loop through the results returned by listeners,
prioritize listeners, and more. Many of these features are detailed in the
examples.
Found a mistake or want to contribute to the documentation? Edit this page on GitHub!