An introduction to ZendEventManager

Zend Framework 2's EventManager is a key component of the framework which is used for the core MVC system. The EventManager allows a class to publish events that other objects can listen for and then act when the event occurs. The convention within Zend Framework 2 is that any class that triggers events composing its own EventManager.


For the purposes of this article, we will use these definitions:

  • An EventManager is an object that holds a collection of listeners for one or more named events, and which triggers events.
  • An event is an action that is triggered by an EventManager.
  • A listener is a callback that can react to an event.

When the EventManager's trigger() method is called, all the listeners attached to the event are called in turn and are passed an Event object which contains a target and additional parameters as required.

Triggering events

A typical use-case for EventManager is to trigger events within a mapper class:

Firstly, note that, by convention, the EventManager instance is called $events and we use a method called events() and that will instantiate the EventManager for us when needed. This is a very common code pattern in ZF2 classes; so common in fact that the ZfcBase module contains a class called ZfcBaseEventManagerEventProvider that you can extend from to provide you with this functionality.

Within our mapper's findById()method, we trigger two events: before and after the actual work is done. When triggering an event, we supply the event's name, the target class and an array of data that the listeners may be interested in.

By convention, we use the name of the method as our event's name. This makes it predictable for users of the class. Also, by convention, if there two events, then we append '.pre' and '.post' to the event name. the target class is usually the class that triggered the event, and so we pass in $this. Finally, we can provide some additional data to the listeners. In this particular method, we supply the id before we retrieve (as that's all we have!) After retrieval, we have the entity object itself, so we supply that to the listener callbacks.

Listening for an event

A listener is just any PHP callback function which takes a single argument, $event, which is an instance of an Event. The listener is attached using event manager's attach() method. For example, we could attach a logger to our mapper's findById.pre event like this:

The $event parameter that is passed to the listener method has three user methods:

  • getName() – Useful when the same listener is attached to multiple events
  • getTarget() – Usually the class that trigger the event
  • getParams() – Retrieve the parameters sent when the event was triggered.

When attaching a listener to an event, you can specify the priority in the third parameter. The larger the number, the earlier the listener is called. i.e. for a listener that you want to be executed first, set the priority to say 1000. For a listener that you want to be executed last, set the priority the -1000. The default priority is 1 and listeners with the same priority are executed in order or priority.

Short circuiting

The return value from trigger() is a ResponseCollection which is a collection of all the returned results from every listener that has been called in reverse order. i.e. the result from the last listener is first in the collection.

As this result is passed back to trigger, we can use it to stop processing of the listeners if something interesting happens. This is known as short-circuiting and we do this by attaching a callback as the last parameter to trigger().

A good example of this is a caching solution on our findById() method. We change it so that it looks like this:

We have added a callback to our trigger() call that returns true if the result returned by a listener is an instance of Photo. This means that we can attach a listener that tries to read a cache for the id. If it finds one, then it returns the cached object. The trigger callback notices and returns true and the ResponseCollection's stopped flag is set to true.

We then test for stopped() and if it has been set, $results->last() contains the Photo entity that we need.


It's common that you may want to set up listeners before the objects with the event manager you need has been instantiated. Good examples are listeners that log or cache. ZF2 comes with the concept of the SharedEventManager. Essentially you attach listeners to the SharedEventManager and then when the particular event manager's trigger() is called, it will also call all the listeners attached to the shared event collection.

There are two ways to access the SharedEventManager: DIC injection into the object where you need it or via a static class called (rather unimaginatively) StaticEventManager. The exact details of how the injection will work are up in the air at the moment as it's expected that some additional defaults will be provided to make it easier in beta 4 and the use of the StaticEventManager will become deprecated.

In either case, the way to attach a listener to the SharedEventManager is the same:

Note that the only change to the attach call is the addition of a new first parameter which is the name of the class where the event manager is to be found. In this case, it's GalleryModelPhotoMapper. The other three parameters are the same: event name, callback and priority.

In terms of execution of listeners with the same priority, those attached directly are executed before those attached via the SharedEventManager.


This article covers how to use the EventManager in your application. The biggest advantage to using EventManager in your application is that you can decouple classes that really shouldn't be coupled together which makes your code easier to write and maintain. In fact, this is so useful, that ZF2's MVC system makes heavy use of EventManager; The module manager, routing, dispatching and the view layer are all implemented using listeners attached to events.