Aller au contenu principal

Les event listeners

Comme leur nom l'indique, les event listeners sont des écouteurs d'événements.

Quand on crée un event listener, on écrit un bout de code qui sera exécuté à l'arrivée d'un événement précis. On indique ensuite quel événement notre listener doit écouter, donc à quel moment il se lancera.

Le Kernel de Symfony​

Le composant symfony/http-kernel est celui qui est chargé de transformer une requête en réponse. On retrouve la logique déjà explorée lorsqu'on parlait de réceptionner une requête, aller chercher des données, générer le rendu d'une vue, puis renvoyer une réponse.

Ce composant est basé sur les événements : il intègre dans son fonctionnement de nombreux endroits où des événements sont lancés, ce qui signifie qu'on peut les écouter et exécuter du code à des moments bien précis de son exécution :

Kernel events

Modification de la réponse​

Pour commencer, modifions la réponse envoyée au client, en ajoutant une en-tête que nous aurons nous-mêmes créée.

Pour inclure l'en-tête à la réponse, nous allons écouter l'événement kernel.response du Kernel. Nous allons donc écrire un listener, puis le configurer pour qu'il écoute cet événement et se déclenche à son arrivée.

On définira l'en-tête comme suit : X-DEVELOPED-BY: MyCorp.

Écriture du listener​

Pour écrire un listener, il suffit d'écrire une classe avec une méthode qui sera lancée :

src/EventListener/AddMyCorpHeaderListener.php

<?php

namespace App\EventListener;

use Symfony\Component\HttpKernel\Event\ResponseEvent;

class AddMyCorpHeaderListener
{
public function addHeader(ResponseEvent $event)
{
$response = $event->getResponse();

$response->headers->add([
'X-DEVELOPED-BY' => 'MyCorp'
]);
}
}

Quand l'événement kernel.response est déclenché, le dispatcher transmet à tous les écouteurs de cet événement un objet de type ResponseEvent (vous avez la liste des objets transmis pour chaque événement ici).

À partir de cet objet, on peut récupérer la réponse qu'on souhaite modifier avec la méthode getResponse. Il ne nous reste plus qu'à ajouter notre propre en-tête.

Configuration du listener​

Pour configurer notre listener et indiquer qu'il écoutera l'événement kernel.response, nous allons modifier le fichier config/services.yaml. Rappelons-nous, toutes les classes qui se trouvent dans le dossier src/ sont enregistrées automatiquement en tant que services. Nous pouvons donc configurer nos services comme nous l'entendons.

Nous allons donc ajouter la configuration spécifique à notre classe de listener, en bas du fichier. Et pour le déclarer en tant que listener, nous allons lui ajouter un tag kernel.event_listener :

config/services.yaml

App\EventListener\AddMyCorpHeaderListener:
tags:
- {
name: kernel.event_listener,
event: kernel.response,
method: "addHeader",
}

Qu'est-ce qu'un tag ?​

Tout comme on peut ajouter des tags à un article, une photo, etc...pour la catégoriser, on peut tagger un service pour le catégoriser et qu'il soit enregistré d'une manière particulière par Symfony.

Ici, en appliquant le tag kernel.event_listener à notre service, nous déclarons à Symfony qu'il s'agit d'un listener. Ensuite, Symfony utilisera les autres attributs kernel.response et method pour identifier précisément à quel moment il doit l'appeler.

Retrouvez les tags inclus dans Symfony ici.

Conséquences de l'ajout du listener​

À présent, si on relance l'application, alors dans la réponse de chaque page qu'on affiche apparaît une nouvelle en-tête X-Developed-By: MyCorp.

Nous sommes donc venus ajouter un brin de logique dans le cycle d'exécution du Kernel de Symfony, et nous n'aurons pas à l'écrire dans tous nos contrôleurs. Seulement le listener, qui se lancera automatiquement au moment convenu, nous permettra d'ajouter cette en-tête dans toutes les réponses qu'on renverra.