Skip to content
CAI
Software that uses CAICheck a score

symfony/event-dispatcher

56.8

Adequate · 26 September 2026

1.7k

lines of production code

PHP

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a high-performance event dispatching component designed for PHP 8.4+ applications. It provides optimized listener management through compiled, scoped, and immutable dispatchers, alongside declarative configuration via attributes and precise execution ordering. The system also includes comprehensive debugging tools for tracing listener execution and integrates tightly with dependency injection containers for efficient compilation and registration.

Features

Compiler passes for event aliases, hot-path optimization, and listener compilation

The DependencyInjection component introduces three new compiler passes to enhance event dispatcher configuration and performance. AddEventAliasesPass allows bundles to register event aliases, hot-path events, and no-preload events via container parameters. CompileListenersPass optimizes the event dispatcher by converting runtime addListener calls into a static map for CompiledEventDispatcher, improving dispatch speed for lazy-loaded listeners. RegisterListenersPass handles the registration of tagged event listeners and subscribers, supporting before/after constraints for ordering, hot-path tagging, and no-preload optimization, while deprecating direct configuration of hot-path and no-preload events in favor of the new AddEventAliasesPass.

DependencyInjection · high confidence

EventDispatcher component introduces compiled and scoped dispatchers with stricter listener management

The EventDispatcher component now includes a new CompiledEventDispatcher for high-performance dispatching using a listener map defined at compile time, and a ScopedEventDispatcher to allow temporary listeners without mutating the shared dispatcher. The legacy Event class has been removed in favor of the contract-based Event, and the interface now extends ListenerIntrospectionInterface. Additionally, the getSubscribedEvents() method now supports named keys with 'before' and 'after' constraints for ordering, and the ImmutableEventDispatcher is provided for read-only access. The old Event class is deleted, and the EventDispatcher now implements the updated interface with stricter type hints and optimized listener handling.

(repo-wide) · high confidence

Introduce AsEventListener attribute for autoconfiguring event listeners

A new AsEventListener attribute has been added to the EventDispatcher component, allowing developers to declaratively configure event listeners directly on classes or methods. This attribute supports specifying the target event, the handler method, execution priority, and the specific event dispatcher to use. It also introduces ordering capabilities via 'before' and 'after' constraints, enabling precise control over the execution sequence of listeners relative to other services, classes, or specific methods.

Attribute · high confidence

New debug components for event listener tracing

Added TraceableEventDispatcher and WrappedListener classes to the Debug namespace. These components wrap the standard event dispatcher to collect data on which listeners are called, their execution times via the Stopwatch, and whether they stop event propagation. This enables the profiler to display detailed 'Logs & Events' information, including called/not-called listeners and their priorities, improving debugging visibility for event-driven applications.

Debug · high confidence

Test coverage

Added test fixtures for AsEventListener attribute scenarios; Added tests for EventDispatcher compiler passes; Added tests for TraceableEventDispatcher and WrappedListener; Added tests for new EventDispatcher components and refactored existing test suite.

Dependencies

Initial composer.json for Symfony EventDispatcher with PHP 8.4+ requirement

This change introduces the composer.json manifest for the symfony/event-dispatcher component. It establishes a minimum PHP version of 8.4.1 and defines dependencies on symfony/deprecation-contracts (^2.5\|^3) and symfony/event-dispatcher-contracts (^3.8). The manifest also specifies development dependencies for testing and integration (such as symfony/config, symfony/dependency-injection, and symfony/framework-bundle) and sets up PSR-4 autoloading while excluding test files from the classmap.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 42 → 57 (+14.4)
  • Rubric changed (rubric-2026.08.15 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 97 → 88 (-8.5)
  • Architecture 69 → 94 (+25.3)
  • Maturity 49 → 47 (-1.9)
  • Readiness 17 → 43 (+26.0)
  • Security 100 → 100 (+0.0)

Resolved (7)

  • Coverage not measured — test suite did not build
  • Dimension evaluation failed
  • Duplicated block (19 lines × 2) (Tests/DependencyInjection/RegisterListenersPassTest.php)
  • Duplicated block (7 lines × 2) (Tests/Debug/TraceableEventDispatcherTest.php)
  • No exposed public API
  • No tests found
  • Test reliability not included

New (22)

  • Change coupling: TraceableEventDispatcher.php ↔ ImmutableEventDispatcher.php (Debug/TraceableEventDispatcher.php)
  • CompileListenersPass.process (cognitive 32) (DependencyInjection/CompileListenersPass.php)
  • CompileListenersPass.process (cyclomatic 17) (DependencyInjection/CompileListenersPass.php)
  • Dependency hygiene PARTLY measured — Composer dependencies read, no committed lock to grade for currency
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no usage examples (README.md)
  • EventDispatcher.getListenerPriority (cognitive 22) (EventDispatcher.php)
  • EventDispatcher.getListenerPriority (cyclomatic 18) (EventDispatcher.php)
  • EventDispatcher.optimizeListeners (cognitive 19) (EventDispatcher.php)
  • EventDispatcher.removeListener (cognitive 26) (EventDispatcher.php)
  • EventDispatcher.removeListener (cyclomatic 20) (EventDispatcher.php)
  • EventDispatcher.sortListeners (cognitive 21) (EventDispatcher.php)
  • Hotspot: DependencyInjection/CompileListenersPass.php (DependencyInjection/CompileListenersPass.php)
  • Hotspot: EventDispatcher.php (EventDispatcher.php)
  • No assertions: testStopwatchEventIsStoppedWhenListenerThrows (Tests/Debug/WrappedListenerTest.php)
  • Off-boarding risk: anonymized user #1
  • Orphaned files with no living knowledge
  • RegisterListenersPass.process (cognitive 75) (DependencyInjection/RegisterListenersPass.php)
  • RegisterListenersPass.process (cyclomatic 37) (DependencyInjection/RegisterListenersPass.php)
  • RegisterListenersPass.sortByConstraints (cognitive 20) (DependencyInjection/RegisterListenersPass.php)
  • …and 2 more

Changes since last survey

  • 18 commits — 17 feature/other, 1 fixes

By area

  • (root) — 9 commits
  • (repo) — 6 commits
  • Debug/TraceableEventDispatcher.php — 2 commits
  • Tests/Debug — 1 commit

Notable commits

  • fix: [DoctrineBridge][EventDispatcher] Fix losing listeners when a lazy listener adds listeners
  • change: Merge branch '6.4' into 7.4
  • change: Merge branch '6.4' into 7.4
  • change: Merge branch '7.4' into 8.1
  • change: Merge branch '7.4' into 8.1
  • change: Merge branch '8.1' into 8.2
  • change: Merge branch '8.1' into 8.2
  • change: Use spl_object_id() instead of spl_object_hash()
  • change: [Contracts][EventDispatcher] Add ListenerIntrospectionInterface
  • change: [DependencyInjection][EventDispatcher] Order tagged services and listeners with before/after constraints
  • change: [EventDispatcher] Add CompiledEventDispatcher
  • change: [EventDispatcher] Allow getSubscribedEvents() to name its keys
  • change: [EventDispatcher] Deprecate mutating the event dispatcher of the container at runtime
  • change: [EventDispatcher] Do not initialize lazy listeners when they cannot match
  • change: [EventDispatcher] Wrap listeners at call time in the traceable dispatcher
  • change: [EventDispatcher][DoctrineBridge] Defer removing lazy listeners instead of initializing them
  • change: [EventDispatcher][HttpKernel] Build the stubs of listeners only when the events panel is displayed
  • change: [EventDispatcher][Messenger] Add ScopedEventDispatcher, stop mutating the dispatcher of the application

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

symfony/event-dispatcher was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 26 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 9f30de957f63eec04454e018713a7e7c420fe3c4 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-a15879f6f801.