A lightweight, type-safe, PSR-14 compliant event dispatcher for modern PHP.
Designed for projects that need a small, well-typed event/message system with first-class callable support, priority ordering, one-time listeners, and propagation control.
Quick links
- Documentation: README (this file)
- Source: src/
- Tests: tests/
- Examples: examples/
- PHP 8.1 or later
- Composer
Install via Composer:
composer require juststeveking/mituse JustSteveKing\Mit\EventDispatcher;
use JustSteveKing\Mit\ListenerProvider;
use JustSteveKing\Mit\Event;
final class UserRegistered extends Event
{
public function __construct(
public readonly string $userId,
public readonly string $email,
) {
parent::__construct();
}
}
$provider = new ListenerProvider();
$dispatcher = new EventDispatcher($provider);
// Register a listener using a first-class callable
$provider->listen(function (UserRegistered $event): void {
echo "Welcome {$event->email}!\n";
});
$dispatcher->dispatch(new UserRegistered('123', 'user@example.com'));Examples
examples/task-scheduler-demo.php— small demo showing scheduling and dispatch.
- PSR-14 compliant Event Dispatcher and Listener Provider
- Type-safe: listeners are matched by type-hinted event parameter
- First-class callable support (e.g.
$object->method(...)) - Priority-based listener ordering
- One-time listeners (
once) and removal (off/clear) - Respect for stoppable propagation (PSR
StoppableEventInterface) - Type hierarchy support: listeners registered for a parent class or interface receive subtype events
$provider->on(SomeEvent::class, fn(SomeEvent $e) => print('low'), priority: -10);
$provider->on(SomeEvent::class, fn(SomeEvent $e) => print('high'), priority: 10);
// high runs before low$provider->once(SomeEvent::class, fn(SomeEvent $e) => print('called once'));$handler = new class {
public function handle(SomeEvent $e): void { /* ... */ }
};
$provider->listen($handler->handle(...));Implement Psr\EventDispatcher\StoppableEventInterface (or extend the provided StoppableEvent helper) and stop propagation in a listener to prevent later listeners from being invoked.
JustSteveKing\Mit\EventDispatcher— PSR-14 dispatcher;dispatch(object $event): objectJustSteveKing\Mit\ListenerProvider— type-safe listener registryon(string $eventType, callable $listener, int $priority = 0): void— register listener for typelisten(callable $listener, int $priority = 0): void— detect event type from callable parameteronce(string $eventType, callable $listener, int $priority = 0): void— one-time listeneroff(string $eventType, callable $listener): void— remove listenerclear(?string $eventType = null): void— clear listeners
JustSteveKing\Mit\Event— simple event base classJustSteveKing\Mit\StoppableEvent— event that implements stoppable propagation
Run the test suite and static analysis locally:
# Install dependencies
composer install --no-interaction --prefer-dist
# Run phpunit
vendor/bin/phpunit
# Run phpstan (static analysis)
vendor/bin/phpstan analyse
# Run pint (style test)
vendor/bin/pint --testContributions welcome. Please open issues for bugs or feature requests and submit pull requests with tests. Follow the repository coding standards (PSR-12), include unit tests for new behavior, and keep changes small and focused.
This project follows semantic versioning. Releases and changelogs appear on GitHub.
Automated releases
- Tags following the
vX.Y.Zpattern will trigger the release workflow which runs tests and publishes a GitHub Release. - To enable automatic Packagist updates on release, add a repository secret named
PACKAGIST_TOKENcontaining your Packagist API token. The release workflow will notify Packagist when the secret is present.
If you discover a security vulnerability, please open a private issue or contact the maintainer directly. Do not disclose sensitive details publicly until a fix is available.
MIT — see the LICENSE file for details.
If you need help using the library, open an issue with a minimal reproducible example and the PHP version you're using.