Doctrine Listener versus Subscriber

SymfonyDoctrine Orm

Symfony Problem Overview


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.

Symfony Solutions


Solution 1 - Symfony

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!

Solution 2 - Symfony

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.

Solution 3 - Symfony

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.

Solution 4 - Symfony

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

Read more on this issue here

Solution 5 - Symfony

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.

Solution 6 - Symfony

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

Solution 7 - Symfony

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnurikabeView Question on Stackoverflow
Solution 1 - SymfonySgoettschkesView Answer on Stackoverflow
Solution 2 - SymfonyRuslan PolutsyganView Answer on Stackoverflow
Solution 3 - SymfonymetalvarezView Answer on Stackoverflow
Solution 4 - SymfonyWiltView Answer on Stackoverflow
Solution 5 - SymfonyLee DavisView Answer on Stackoverflow
Solution 6 - SymfonyKaizoku GambareView Answer on Stackoverflow
Solution 7 - SymfonyYassine CHABLIView Answer on Stackoverflow