A little more advanced ZF2 EventManager usage

<note>I found out that this usage is going to be deprecated.  This feature will remain, but for the GA (and beta 4 most likely) this code may not work.  I will be updating this blog post when that happens</note>

If you look at my previous post on the ZF2 EventManager class you might be tempted to think that you are limited only to listening to events for local instances of the event manager.  But no, my friend, you would be wrong.

The event manager actually provides access to a sort of global event manager.  But it’s more than that.  This global event manager allows you to listen in on events for various targets.

So let’s say that you have an event manager for a given class in a given namespace.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
namespace ns1 {
 
  use Zend\EventManager\EventManager;
 
  class cls1 {
 
    protected $events;
 
    public function __construct()
    {
      $this->events = new EventManager(__CLASS__);
    }
 
    public function execute()
    {
      $this->events->trigger('meesa.triggered', $this);
    }
  }
}

Take a look at the constructor.  What you are doing there is giving the event manager an identifier.  Identifiers are not needed, but if you want to allow other event manager instances to attach to its events an identifier will make it globally known.

Next up we will create a class that attaches to that event manager by calling the StaticEventManager class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
namespace ns2 {
 
  use Zend\EventManager\Event,
  Zend\EventManager\StaticEventManager;
 
  class cls2 {
 
    public function listen(Event $e)
    {
      echo get_class($this) . ' has been called by ' . get_class($e->getTarget());
    }
  }
 
  StaticEventManager::getInstance()->attach('ns1\cls1', 'meesa.triggered', array(new cls2, 'listen'));
}

We’re not calling the class ns1\cls1 in this case, just attaching to its event.  When setting this up we attach to the identifier that we provided in the first class (often a class name), followed by the event name and them providing the  class and method name via a callback.  When the event is triggered that callback will be called and we will we will  print out the target class.

1
2
3
4
use ns1\cls1;
 
$cls = new cls1();
$cls->execute();

When we execute that code we get the following output.

ns2\cls2 has been called by ns1\cls1

So even though ns2\cls2 and ns1\cls1 had virtually no knowledge of each other (we did because we “set them up to succeed”), we were able to call code from across the codebase with great ease.

About the author

Kevin Schroeder

View all posts

6 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *