Faire passer son listener avant celui d'un bundle, sans jouer aux devinettes avec des nombres
Tout développeur Symfony a déjà connu ce moment : un listener d'un bundle tiers modifie la requête ou la réponse, le vôtre doit passer juste avant (ou juste après), et il faut ouvrir le profiler pour trouver la priorité du voisin. Symfony 8.2 s'attaque à ce point de friction avec un classement relatif pour les listeners et les services.
Le problème des priorités numériques
Aujourd'hui, l'ordre d'exécution de plusieurs listeners sur un même événement repose sur un entier. Plus la valeur est élevée, plus le listener s'exécute tôt. Par défaut, la priorité vaut 0.
#[AsEventListener(event: KernelEvents::REQUEST, priority: 10)]
final class TenantResolverListener
{
public function __invoke(RequestEvent $event): void
{
// ...
}
}
Ce mécanisme fonctionne, mais il porte une faiblesse structurelle : le nombre choisi n'a de sens que par rapport aux autres listeners, que vous ne maîtrisez pas toujours. Quelques situations typiques :
- vous devez passer avant un listener du framework ou d'un bundle, il faut donc retrouver sa priorité exacte et viser un cran au-dessus
- vous devez passer après, et vous prenez une valeur extrême (comme -255 ou 255) en espérant que personne ne l'utilisera aussi
- une mise à jour du bundle change sa priorité interne, et votre ordre d'exécution casse sans aucun message d'erreur
Le vrai défaut n'est pas la difficulté technique, c'est que l'intention (« avant celui-là ») n'est écrite nulle part. Elle est encodée dans un chiffre qu'il faut décoder à chaque relecture.
Ce qu'apporte le classement relatif
Symfony 8.2 introduit la possibilité d'exprimer l'ordre par rapport à un autre listener ou à un autre service, plutôt que par une valeur absolue. Le code dit ce qu'il veut : s'exécuter avant ou après un élément donné. La résolution de l'ordre final revient au conteneur, qui n'a plus besoin que vous connaissiez les priorités numériques de vos voisins.
Les bénéfices attendus sont concrets :
- Lisibilité : la contrainte d'ordre est explicite dans le code, un relecteur comprend l'intention sans calcul
- Robustesse : si un bundle ajuste sa priorité interne, votre contrainte relative continue de s'appliquer
- Moins de valeurs magiques : fini les nombres extrêmes posés « au cas où » et jamais documentés
L'intérêt dépasse les seuls événements. Le titre de l'évolution parle aussi de services : les mécanismes de Symfony qui exécutent des services dans un ordre donné profitent de la même logique, ce qui uniformise la façon de penser l'ordonnancement dans le framework.
La fonctionnalité a été contribuée par Nicolas Grekas (pull requests #66012, #66022 et #66240). La syntaxe exacte, les options disponibles et les cas limites (par exemple deux contraintes contradictoires) sont détaillés dans l'annonce officielle et dans la documentation de la version : consultez-les avant de migrer votre code, car cet article ne les reproduit pas.
Comment l'adopter proprement
Il n'y a aucune urgence à tout réécrire. Une approche progressive donne de bons résultats :
- repérer dans votre projet les listeners dont la priorité est choisie uniquement pour passer avant ou après un composant précis
- commencer par les cas où la valeur actuelle est extrême ou accompagnée d'un commentaire du type « ne pas toucher »
- convertir ces cas vers le classement relatif lors du passage à Symfony 8.2, et vérifier l'ordre obtenu avec la commande de debug des événements du framework
- conserver les priorités numériques là où elles expriment un vrai niveau (par exemple un traitement très précoce, indépendant de tout voisin)
Un bon réflexe consiste aussi à couvrir l'ordre par un test : si l'ordre d'exécution compte pour votre logique métier, il mérite une vérification automatique plutôt qu'une confiance aveugle dans la configuration.
En résumé
Le classement relatif ne change pas ce que Symfony sait faire, il change la façon de le dire. Exprimer « avant » ou « après » plutôt qu'un entier rend le code plus honnête, réduit les régressions silencieuses lors des mises à jour de bundles et simplifie la cohabitation avec du code qu'on ne contrôle pas. Pour les équipes qui empilent plusieurs bundles, c'est un gain de maintenance appréciable.
Pour aller plus loin, lisez l'annonce d'origine : New in Symfony 8.2: Relative Ordering for Listeners and Services.
Et votre site, il vaut quoi ?
Vitesse, accessibilité, référencement technique. Le rapport est écrit pour un dirigeant, pas pour un développeur. Gratuit, sans inscription.