notiziephp.it

Novità in Symfony 8.2: Event Dispatcher compilato (Symfony Blog)

Traduzione da Symfony Blog
7 Ottobre 2026 Tempo di lettura: 3 minuti
Novità in Symfony 8.2: Event Dispatcher compilato (Symfony Blog)

Symfony 8.2 include molti miglioramenti delle prestazioni, ma continuiamo a cercare nuove opportunità per rendere le tue applicazioni più veloci.

Ad esempio, Symfony crea l'event dispatcher a runtime per ogni richiesta chiamando addListener() per ciascun listener e avvolgendolo in una closure, anche per eventi che la richiesta non invia mai. Ma Symfony conosce già gli event listener della tua applicazione quando compila il container, quindi questo lavoro può essere fatto in anticipo.

In Symfony 8.2, il servizio event_dispatcher è un CompiledEventDispatcher. Riceve un array di ID dei servizi listener e dei metodi, nell'ordine in cui vengono eseguiti, e un service locator per caricarli quando servono. L'OPcache di PHP memorizza l'array in memoria condivisa, così ogni richiesta non ha bisogno della propria copia.

In un benchmark con 75 listener su 31 eventi, la creazione del dispatcher ha richiesto 0,48 µs, in calo rispetto a 33,7 µs. Le closure dei listener occupavano prima circa 97 KB di memoria; il dispatcher compilato non ne ha bisogno.

L'invio degli eventi è veloce come prima. I servizi listener vengono comunque creati solo quando stanno per essere eseguiti. Se un evento non viene mai inviato, o un listener interrompe la sua propagazione, i listener rimanenti non vengono istanziati.

Le registrazioni esistenti di listener e subscriber ne beneficiano automaticamente. Il profiler e debug:event-dispatcher funzionano come prima.

Aggiungere o rimuovere un listener a runtime costringe il dispatcher compilato a ricadere su un normale EventDispatcher, perdendo il vantaggio in termini di prestazioni. Symfony 8.2 depreca quindi la chiamata a addListener(), addSubscriber(), removeListener() o removeSubscriber() sul servizio condiviso event_dispatcher. Queste chiamate attivano deprecazioni anche in dev, dove puoi vederle nel profiler.

Registra invece i tuoi listener come servizi. Per i listener temporanei, come quelli necessari durante l'esecuzione di un comando console, usa il nuovo ScopedEventDispatcher. Avvolge il dispatcher condiviso e mantiene i listener aggiuntivi senza aggiungerli al servizio condiviso. Solo gli eventi inviati tramite il wrapper raggiungono quei listener:

Il wrapper chiama entrambi i gruppi di listener in ordine di priorità. Symfony lo usa nei comandi messenger:consume e messenger:failed:retry.

Controlla anche i tuoi test funzionali. Se un test aggiunge un listener al servizio condiviso event_dispatcher per verificare che un evento sia stato inviato, registra quel listener come servizio nell'ambiente di test.

Anche l'autowiring del dispatcher condiviso con Symfony\Component\EventDispatcher\EventDispatcherInterface è deprecato, perché quell'interfaccia include metodi per modificare i listener. Se il tuo servizio si limita a inviare eventi, passa all'interfaccia dei contracts:

Per ispezionare i listener registrati, ad esempio in uno strumento di debug, usa l'autowiring di Symfony\Contracts\EventDispatcher\ListenerIntrospectionInterface. Questa nuova interfaccia fornisce getListeners(), getListenerPriority() e hasListeners(). Se devi anche inviare eventi, combina entrambe le interfacce con un intersection type:

Condividi su: LinkedIn

Altri articoli recenti