Symfony (comme beaucoup de framework) émét des événements à chaque étape de son cycle de vie (préparation de la requête, traitement de la requête, génération de la réponse, etc.). Ces événements peuvent être écoutés par des listeners qui peuvent modifier le comportement de Symfony.
Les événements permettent aussi d'éviter de surcharger un contrôleur ou un service. Par exemple, un utilisateur s'inscrit sur votre site. Vous souhaitez lui envoyer un email, puis une notifaction push et notifier d'autres utilisateurs d'un nouvel inscrit par exemple.
Vous pourriez ajouter ces fonctionnalités dans le contrôleur qui gère l'inscription. Mais si vous avez besoin de faire la même chose dans un autre contrôleur, vous allez devoir dupliquer le code.
Si vous souhaitez retirer l'un des comportements, vous allez devoir le retirer dans tous les contrôleurs qui l'utilisent.
Si vous souhaitez ajouter un comportement vous allez devoir modifier tous les contrôleurs qui l'utilisent.
Les points 2 et 3 ne sont pas forcément problèmatique si vous êtes propriétaire du code. Mais si vous développez un bundle ou utilisez un bundle existant, vous ne pourrez peut etre pas modifier le code.
Dans ces trois exemples il est donc possible de définir nos événements qui pourront ensuite être écoutés par un ou plusieurs listeners, qui chacun pourra mener une action.
Nous allons donc voir dans cette partie comment écouter des événements, et comment définir nos propres événements.
Symfony (ou votre application) émet des événements à chaque étape de son cycle de vie. Ces événements sont écoutés par des listeners qui peuvent modifier le comportement de Symfony.
Pour écouter un événement, il faut créer une classe qui implémente l'interface Symfony\Component\EventDispatcher\EventSubscriberInterface
. Cette interface contient une méthode getSubscribedEvents()
qui retourne un tableau associatif. La clé est le nom de l'événement et la valeur est la méthode à appeler.
Un exemple pourrait être :
Dans cet exemple, la méthode onKernelRequest()
sera appelée à chaque fois que l'événement kernel.request
sera émis.
Il existe aussi la possibilité de définir des listener avec une syntaxe différente qui ne va écouter qun' seul événement précis : https://symfony.com/doc/current/event_dispatcher.html#creating-an-event-listener
https://symfony.com/doc/current/components/event_dispatcher.html
Pour définir nos propres événements il faut deux choses :
Définir une classe qui hérite de Symfony\Component\EventDispatcher\Event
qui va contenir la description et les données de notre événement.
"Emettre" l'événement avec la méthode dispatch()
de l'objet Symfony\Component\EventDispatcher\EventDispatcherInterface
quelque part dans notre application en lui passant un objet du type de la classe de l'événnement précédemment créée.
Pour définir notre événement, il faut créer une classe qui hérite de Symfony\Component\EventDispatcher\Event
. Cette classe doit contenir les données de l'événement. Par exemple, si nous voulons définir un événement qui sera émis à chaque fois qu'un utilisateur s'inscrit, nous pourrions avoir une classe comme celle-ci :
Pour émettre l'événement, il faut récupérer l'objet Symfony\Component\EventDispatcher\EventDispatcherInterface
et appeler la méthode dispatch()
en lui passant en premier paramètre le nom de l'événement et en second paramètre l'objet de l'événement.
Et bien sûr définir un listener pour écouter l'événement, comme décrit dans la partie précédente, et qui pourrait être pour notre exemple :
Créer un événement UserRegisteredEvent
qui sera émis à chaque fois qu'un utilisateur s'inscrit. Créer un listener qui enverra un email (en utilisant notre service) à l'utilisateur pour lui dire qu'il a bien été enregistré.
Créer un deuxième événement UserUpdatedEvent
qui sera émis à chaque fois qu'un utilisateur met à jour son profil. Créer un listener qui enverra un email (en utilisant notre service) à l'utilisateur pour lui dire qu'il a bien été mis à jour.