sylius-labs/polyfill-symfony-event-dispatcher
Symfony EventDispatcher Polyfill for projects that need compatible event dispatching without depending on a specific Symfony EventDispatcher version. Useful for libraries and apps supporting multiple Symfony versions or minimizing hard dependencies.
Installation
composer require sylius-labs/polyfill-symfony-event-dispatcher
Add to composer.json under require or require-dev depending on your needs.
First Use Case
Replace legacy event dispatching logic with Symfony’s EventDispatcherInterface:
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use SyliusLabs\PolyfillSymfonyEventDispatcher\EventDispatcher;
// Initialize (if not using DI)
$dispatcher = new EventDispatcher();
// Dispatch an event
$dispatcher->dispatch(new MyEvent(), 'my.event');
Where to Look First
EventDispatcher docs for API reference (this polyfill mirrors it).src/EventDispatcher.php for implementation details (if extending).Event Listener Registration Register listeners dynamically or statically:
$dispatcher->addListener('event.name', [$listener, 'handle']);
$dispatcher->addSubscriber(new MySubscriber());
Event Dispatching Dispatch events with optional priority:
$dispatcher->dispatch($event, 'event.name', 10); // Priority 10
Integration with Laravel Bind the polyfill to Laravel’s service container:
$app->singleton(EventDispatcherInterface::class, function ($app) {
return new EventDispatcher();
});
Use in controllers/services:
public function __construct(private EventDispatcherInterface $dispatcher) {}
Legacy Code Migration
Replace old-style event systems (e.g., custom EventManager) with the polyfill:
// Before:
$eventManager->trigger('event.name', $event);
// After:
$dispatcher->dispatch($event, 'event.name');
EventSubscriberInterface.Event::stopPropagation() in listeners to halt further dispatching.PHP Version Compatibility
EventDispatcher for PHP 8.0+.composer.json constraints).Listener Ordering
addListener(..., 20)) for control.Event Object Mutability
Circular Dependencies
EventA dispatching EventB which re-dispatches EventA).Listener Not Firing? Verify the event name matches exactly (case-sensitive) and the listener method signature:
// Correct:
$dispatcher->addListener('user.created', [$userService, 'handleUserCreated']);
// Incorrect (wrong name or method):
$dispatcher->addListener('user.created', [$userService, 'handleUserCreatedEvent']);
Performance Bottlenecks
Use addSubscriber() for groups of listeners to reduce overhead.
Testing
Mock EventDispatcherInterface in tests:
$mockDispatcher = $this->createMock(EventDispatcherInterface::class);
$mockDispatcher->expects($this->once())->method('dispatch');
Custom EventDispatcher
Extend EventDispatcher to add middleware or logging:
class CustomDispatcher extends EventDispatcher {
public function dispatch($event, string $eventName = null, int $priority = 0) {
Log::debug("Dispatching {$eventName}");
parent::dispatch($event, $eventName, $priority);
}
}
Global Event Namespaces
Prefix event names to avoid collisions (e.g., app.user.created instead of user.created).
Laravel-Specific
Publish config or bind the dispatcher to Laravel’s events facade:
Event::listen('event.name', function () { /* ... */ });
(Requires additional binding logic.)
How can I help you explore Laravel packages today?