Ce qui se passe
Pour qu'un listener passe avant celui d'un bundle ou du framework, il fallait
jusqu'ici lire la priorité de l'autre, prendre un nombre un peu plus haut et
espérer qu'elle ne bouge pas à la prochaine mise à jour. Symfony 8.2 ajoute deux
options, before et after, qui désignent directement le listener ou le
service tagué à précéder ou à suivre. Contribution de Nicolas Grekas,
#66012.
Pour les listeners
Les options prennent un identifiant de service, un nom de classe, ou un tableau des
deux. Un suffixe ::méthode vise une méthode précise. Il compte avec
LocaleListener, qui écoute kernel.request par deux méthodes : sans suffixe,
votre listener passerait avant les deux.
Le cas d'usage du billet : un listener qui pose l'attribut de requête _locale doit
s'exécuter avant que LocaleListener ne le lise.
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\EventListener\LocaleListener;
#[AsEventListener(before: LocaleListener::class.'::onKernelRequest')]
final class LocaleFromHeaderListener
{
public function __invoke(RequestEvent $event): void
{
// pose $event->getRequest()->attributes->set('_locale', …)
}
}Les subscribers déclarés comme services profitent des mêmes options, et
getSubscribedEvents() accepte désormais des clés nommées comme method et
priority.
Les règles
- l'ordre est calculé à la compilation du conteneur : rien ne s'ajoute à l'exécution ;
- sans priorité, Symfony en choisit une ; avec une priorité explicite, les contraintes ne réordonnent qu'à l'intérieur de ce niveau ;
- une référence vers un listener absent de l'événement est ignorée, ce qui permet de viser un bundle optionnel ;
- priorités contradictoires, cycles et méthodes invalides font échouer la compilation.
Services tagués et décorateurs
before et after valent aussi pour les services tagués, via #[AsTaggedItem] ou
la configuration du tag. L'exemple du billet : un bundle d'import fournit des
gestionnaires CSV et XLSX de même priorité, et vous voulez glisser un gestionnaire
TSV entre les deux. Attention, AsTaggedItem fixe l'ordre mais n'ajoute pas le
tag : le service doit déjà le porter, par autoconfiguration par exemple.
Les décorateurs souffraient du même mal, empilés selon leur priorité. Deux options
arrivent : within liste les décorateurs qui enveloppent le vôtre, around
ceux que le vôtre enveloppe. Pour signer chaque requête HTTP sortante, nouvelles
tentatives comprises, votre décorateur doit se trouver à l'intérieur de
RetryableHttpClient : c'est lui que within désigne. Mêmes règles que
before/after, et compatibles avec #[AsTagDecorator].
Source : New in Symfony 8.2: Relative Ordering for Listeners and Services, blog Symfony, 6 octobre 2026. Documentation 8.2 : listeners, services tagués, décorateurs.