Doctrine Listener versus Subscriber

I'm working in the Symfony2 framework and wondering when would one use a Doctrine subscriber versus a listener. Doctrine's documentation for listeners is very clear, however subscribers are rather glossed over. Symfony's cookbook entry is similar.

28285 次浏览

Both allow you to execute something on a particular event pre / post persist etc.

However listeners only allow you to execute behaviours encapsulated within your Entity. So an example might be updating a "date_edited" timestamp.

If you need to move outside the context of your Entity, then you'll need a subscriber. A good example might be for calling an external API, or if you need to use / inspect data not directly related to your Entity.

From my point of view, there is only one major difference:

  • The Listener is signed up specifying the events on which it listens.
  • The Subscriber has a method telling the dispatcher what events it is listening to

This might not seem like a big difference, but if you think about it, there are some cases when you want to use one over the other:

  • You can assign one listener to many dispatchers with different events, as they are set at registration time. You only need to make sure every method is in place in the listener
  • You can change the events a subscriber is registered for at runtime and even after registering the subscriber by changing the return value of getSubscribedEvents (Think about a time where you listen to a very noisy event and you only want to execute something one time)

There might be other differences I'm not aware of though!

You should use event subscriber when you want to deal with multiple events in one class, for example in this symfony2 doc page article, one may notice that event listener can only manage one event, but lets say you want to deal with several events for one entity, prePersist, preUpdate, postPersist etc... if you use event listener you would have to code several event listener, one for each event, but if you go with event subscriber you just have to code one class the event susbcriber, look that with the event subscriber you can manage more than one event in one class, well thats the way i use it, i preffer to code focused in what the model business need, one example of this may be went you want to handle several lifecycle events globaly only for a group of your entities, to do that you can code a parent class and defined those global methods in it, then make your entities inherit that class and later in your event susbcriber you subscribe every event you want, prePersist, preUpdate, postPersist etc... and then ask for that parent class and execute those global methods.

Don't know whether it is done accidentally or intentionally.. But subscribers have higher priority that listeners - https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php#L73-L98

From doctrine side, it doesn't care what it is (listener or subscriber), eventually both are registered as listeners - https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/EventManager.php#L137-L140

This is what I spotted.

Another important thing: Doctrine EventSubscribers do not allow you to set a priority.

Read more on this issue here

Here is what the doc is saying about that in 4.1. As this is globally applied to events, I suppose it's also valid for Doctrine (not 100% sure).

Listeners or Subscribers

Listeners and subscribers can be used in the same application indistinctly. The decision to use either of them is usually a matter of personal taste. However, there are some minor advantages for each of them:

  • Subscribers are easier to reuse because the knowledge of the events is kept in the class rather than in the service definition. This is the reason why Symfony uses subscribers internally;
  • Listeners are more flexible because bundles can enable or disable each of them conditionally depending on some configuration value.

http://symfony.com/doc/master/event_dispatcher.html#listeners-or-subscribers

From the documentation :

The most common way to listen to an event is to register an event listener with the dispatcher. This listener can listen to one or more events and is notified each time those events are dispatched.

Another way to listen to events is via an event subscriber. An event subscriber is a PHP class that's able to tell the dispatcher exactly which events it should subscribe to. It implements the EventSubscriberInterface interface, which requires a single static method called getSubscribedEvents().

See the example here :

https://symfony.com/doc/3.3/components/event_dispatcher.html