naingaunglwin-dev/event-dispatcher

A lightweight and flexible PHP Event Dispatcher package fully compliant with PSR-14

Installs: 1

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 1

Forks: 0

Open Issues: 0

pkg:composer/naingaunglwin-dev/event-dispatcher

v1.0.0 2026-01-26 18:04 UTC

This package is auto-updated.

Last update: 2026-01-27 08:28:51 UTC


README

Event-Dispatcher

GitHub CI Status Code Coverage License

A lightweight PHP Event Dispatcher that follows PSR-14, with optional helpers and facade for ergonomic usage.

Contributing

  • This is an open-source library, and contributions are welcome.
  • If you have any suggestions, bug reports, or feature requests, please open an issue or submit a pull request on the project repository.

Requirement

  • PHP version 8.4 or newer is required
  • composer

Installation

composer require naingaunglwin-dev/event-dispatcher

Features

  • PSR-14 compliant core dispatcher
  • Stoppable events (stopPropagation())
  • One-time listeners (once())
  • Payload support with GenericEvent
  • User-friendly Support\Event helper
  • Static Facade\Event API for Laravel-style usage
  • Lightweight and easy to extend

Core Concepts

This package provides a PSR-14 compliant core and optional helpers.

  • Core (PSR-14)
    • EventDispatcher
    • ListenerProvider
    • StoppableEvent
  • Extras (Framework-friendly)
    • GenericEvent (string-based events with payload)
    • Support\Event helper
    • Facade\Event (Laravel-style static API)

You may use only the core, or opt into the helpers.

Usage

1️⃣ GenericEvent (String-based Events)

Use GenericEvent when you want string-based events with a mutable payload.

  • Example
use Naingaunglwin\EventDispatcher\EventDispatcher;
use Naingaunglwin\EventDispatcher\ListenerProvider;
use Naingaunglwin\EventDispatcher\GenericEvent;

$provider = new ListenerProvider();
$dispatcher = new EventDispatcher($provider);

$provider->addListener('init', function (GenericEvent $event) {
    $event->setPayload('foo', 'bar');
});

$provider->addListener('init', function (GenericEvent $event) {
    echo $event->getPayload('foo') . PHP_EOL;
});

$dispatcher->dispatch(new GenericEvent('init'));

Description

  • GenericEvent allows non-class-based events
  • Payload is mutable and shared across listeners
  • Fully compatible with stoppable propagation

2️⃣ Class-based Events (Recommended)

Class-based events are the preferred PSR-14 approach.

  • Define an Event
use Naingaunglwin\EventDispatcher\StoppableEvent;

class UserRegistered extends StoppableEvent
{
    public function __construct(
        public readonly string $username
    ) {}
}
  • Register Listeners
$provider->addListener(UserRegistered::class, function (UserRegistered $event) {
    echo "User registered: {$event->username}" . PHP_EOL;
});
  • Dispatch the Event
$dispatcher->dispatch(new UserRegistered('john'));

3️⃣ Class-based Listeners (__invoke)

Listeners may be invokable classes

  • Listener Class
class SendWelcomeEmail
{
    public function __invoke(UserRegistered $event): void
    {
        echo "Sending welcome email to {$event->username}" . PHP_EOL;
    }
}

Register the Listener

$provider->addListener(UserRegistered::class, new SendWelcomeEmail());

4️⃣ Stoppable Events

Listeners can stop further propagation.

  • Example
$provider->addListener(UserRegistered::class, function (UserRegistered $event) {
    if ($event->username === 'admin') {
        $event->stopPropagation();
    }
});

$provider->addListener(UserRegistered::class, function () {
    echo "This will not run if propagation is stopped";
});

5️⃣ One-time Listeners (once)

One-time listeners are removed automatically after execution.

$provider->addOnceListener('init', function () {
    echo "This runs only once" . PHP_EOL;
});

6️⃣ Support\Event Helper (User-friendly API)

The Support\Event helper wraps the core dispatcher for convenience.

  • Example
use Naingaunglwin\EventDispatcher\Support\Event;
use Naingaunglwin\EventDispatcher\GenericEvent;

$event = new Event();

$event->on('init', function (GenericEvent $event) {
    $event->setPayload('foo', 'bar');
});

$event->once('init', function () {
    echo "Run once" . PHP_EOL;
});

$event->on('init', function (GenericEvent $event) {
    echo $event->getPayload('foo') . PHP_EOL;
});

$event->dispatch(new GenericEvent('init'));
$event->dispatch(new GenericEvent('init'));

Description

  • Simplifies listener registration
  • Manages provider and dispatcher internally
  • Still uses PSR-14 compliant core internally

7️⃣ Facade\Event (Static API)

For maximum ergonomics, use the facade.

Example

use Naingaunglwin\EventDispatcher\Support\Facade\Event;
use Naingaunglwin\EventDispatcher\GenericEvent;

Event::on('init', function (GenericEvent $event) {
    $event->setPayload('foo', 'bar');
});

Event::once('init', function () {
    echo "Just once" . PHP_EOL;
});

Event::on('init', function (GenericEvent $event) {
    echo $event->getPayload('foo') . PHP_EOL;
});

Event::dispatch('init');
Event::dispatch('init');

Resetting the Facade

  • Useful for tests or long-running processes:
Event::reset();