sugiphp / events
PSR-14 Event Dispatcher
Requires
- php: >=5.3
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-15 07:56:04 UTC
README
A minimal, dependency-light PSR-14 event dispatcher for PHP 8.3+.
It provides:
Dispatcher— a PSR-14EventDispatcherInterfaceimplementation that calls listeners in registration order and stops onStoppableEventInterface.ListenerProvider— a PSR-14ListenerProviderInterfaceimplementation that maps an event class (or any of its parent classes / interfaces) to the listeners registered for it.EventDispatcherTrait— an optional trait to add dispatching capability to any class without requiring a hard dependency onDispatcherin its constructor.
Installation
composer require sugiphp/events ^2.0
Basic usage
use SugiPHP\Events\Dispatcher; use SugiPHP\Events\ListenerProvider; $provider = new ListenerProvider(); $provider->addListener(UserRegistered::class, function (UserRegistered $event) { // send a welcome email, etc. }); $dispatcher = new Dispatcher($provider); $event = new UserRegistered($user); $dispatcher->dispatch($event);
Any PHP object can be used as an event — there is no base Event class or interface to extend.
Registering listeners
ListenerProvider::addListener() takes an event class (or interface) name and any PHP callable:
$provider->addListener(UserRegistered::class, new SendWelcomeEmail()); $provider->addListener(UserRegistered::class, [$logger, 'logRegistration']); $provider->addListener(UserRegistered::class, 'notify_admins');
Listeners are invoked in the order they were registered. Registering against a parent class or
an interface matches every event that instanceof that type:
interface DomainEvent {} class UserRegistered implements DomainEvent {} // Fires for UserRegistered and any other DomainEvent implementation. $provider->addListener(DomainEvent::class, $auditLogger);
Stopping propagation
Events that implement Psr\EventDispatcher\StoppableEventInterface can stop remaining listeners
from being called:
use Psr\EventDispatcher\StoppableEventInterface; class UserRegistered implements StoppableEventInterface { private bool $stopped = false; public function isPropagationStopped(): bool { return $this->stopped; } public function stopPropagation(): void { $this->stopped = true; } }
Once a listener calls stopPropagation(), Dispatcher::dispatch() stops calling any further
listeners and returns the event as-is.
Using the trait
EventDispatcherTrait lets a class expose a dispatch() method without requiring a Dispatcher
to be injected through its constructor. If no dispatcher has been set, dispatch() is a no-op
that returns the event unchanged.
use SugiPHP\Events\Dispatcher; use SugiPHP\Events\EventDispatcherTrait; use Psr\EventDispatcher\EventDispatcherInterface; class UserService implements EventDispatcherInterface { use EventDispatcherTrait; } $service = new UserService(); $service->setEventDispatcher(new Dispatcher($provider)); $service->dispatch(new UserRegistered($user));
Requirements
- PHP >= 8.3
- psr/event-dispatcher ^1.0
Testing
composer test
License
MIT