PHPackages                             phpnomad/event - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. phpnomad/event

ActiveLibrary[Framework](/categories/framework)

phpnomad/event
==============

1.0.1(3w ago)06.3k↓35%[1 issues](https://github.com/phpnomad/event/issues)[1 PRs](https://github.com/phpnomad/event/pulls)10MITPHPCI passing

Since Jan 31Pushed 3w ago2 watchersCompare

[ Source](https://github.com/phpnomad/event)[ Packagist](https://packagist.org/packages/phpnomad/event)[ Docs](https://github.com/phpnomad/core)[ RSS](/packages/phpnomad-event/feed)WikiDiscussions main Synced 3d ago

READMEChangelog (2)Dependencies (2)Versions (7)Used By (10)

phpnomad/event
==============

[](#phpnomadevent)

[![Latest Version](https://camo.githubusercontent.com/f5605c55bb265b743814185a05bc45060458ef87db5becfc88686bbe4ea2874b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7068706e6f6d61642f6576656e742e737667)](https://packagist.org/packages/phpnomad/event)[![Total Downloads](https://camo.githubusercontent.com/0ad6bd237a4ea6feffdbaac059d780b594b33b0884886ca0422eeae30f7739ae/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7068706e6f6d61642f6576656e742e737667)](https://packagist.org/packages/phpnomad/event)[![PHP Version](https://camo.githubusercontent.com/e0738c29c5e13855dbf816cfbd60fb82cb71638757795c85a15f486f97187ac3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f7068706e6f6d61642f6576656e742e737667)](https://packagist.org/packages/phpnomad/event)[![License](https://camo.githubusercontent.com/b78b1e526546b5b028ca82a43c55290bb3ab46855fc20b5af408df3735ee8f49/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f7068706e6f6d61642f6576656e742e737667)](https://packagist.org/packages/phpnomad/event)

`phpnomad/event` provides interfaces for event-driven architecture in PHP applications. Components broadcast events when something happens, and listeners react without the publisher needing to know who is listening. That lets you add behavior like sending a welcome email, updating a cache, or writing an audit log by writing a new handler instead of modifying existing code.

This package is interfaces only. It has zero runtime dependencies and it does not ship a dispatcher. For a working event system you also install a concrete implementation. The recommended one is [`phpnomad/symfony-event-dispatcher-integration`](https://packagist.org/packages/phpnomad/symfony-event-dispatcher-integration), which adapts Symfony's EventDispatcher to the `EventStrategy` contract. The package is used in production by [Siren](https://sirenaffiliates.com) and by every PHPNomad package that needs to broadcast or listen for events.

Installation
------------

[](#installation)

```
composer require phpnomad/event
```

For a working dispatcher, also install the Symfony integration:

```
composer require phpnomad/symfony-event-dispatcher-integration
```

Quick Start
-----------

[](#quick-start)

Define an event. It just needs a stable identifier and whatever payload you want handlers to see.

```
use PHPNomad\Events\Interfaces\Event;

class UserCreatedEvent implements Event
{
    public function __construct(
        public readonly int $userId,
        public readonly string $email
    ) {}

    public static function getId(): string
    {
        return 'user.created';
    }
}
```

Write a handler that reacts to the event.

```
use PHPNomad\Events\Interfaces\CanHandle;
use PHPNomad\Events\Interfaces\Event;

class SendWelcomeEmailHandler implements CanHandle
{
    public function __construct(private EmailService $email) {}

    public function handle(Event $event): void
    {
        $this->email->send($event->email, 'Welcome!');
    }
}
```

Declare the event-to-handler mapping on a module so the bootstrapper can wire it up.

```
use PHPNomad\Events\Interfaces\HasListeners;

class UserModule implements HasListeners
{
    public function getListeners(): array
    {
        return [
            UserCreatedEvent::class => SendWelcomeEmailHandler::class,
        ];
    }
}
```

Broadcast the event from wherever the state change actually happens.

```
use PHPNomad\Events\Interfaces\EventStrategy;

class UserService
{
    public function __construct(private EventStrategy $events) {}

    public function createUser(string $email): User
    {
        $user = new User($email);
        // persist the user...

        $this->events->broadcast(new UserCreatedEvent(
            userId: $user->getId(),
            email: $user->getEmail()
        ));

        return $user;
    }
}
```

The `UserService` has no knowledge of `SendWelcomeEmailHandler`. Adding a second handler for logging, analytics, or a Slack notification is a new class and one extra line in `getListeners()`. The service code does not change.

Key Concepts
------------

[](#key-concepts)

- `Event`: an object representing something that happened, identified by a static `getId()` string
- `EventStrategy`: the dispatcher interface with `broadcast()`, `attach()`, and `detach()`
- `CanHandle`: the contract a handler implements to react to an event
- `HasListeners`: modules implement this to declare their event-to-handler mappings
- `HasEventBindings`: flexible binding configuration for platform integration layers
- `ActionBindingStrategy`: bridges external systems like WordPress hooks into application events

Documentation
-------------

[](#documentation)

Full documentation, including the interface reference and event design best practices, lives at [phpnomad.com](https://phpnomad.com).

License
-------

[](#license)

MIT. See [LICENSE.txt](LICENSE.txt).

###  Health Score

48

—

FairBetter than 93% of packages

Maintenance95

Actively maintained with recent releases

Popularity24

Limited adoption so far

Community22

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 81.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~540 days

Total

2

Last Release

23d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/9e6206223bd6f2a57b8ac80605b1b5c3521faaec18ad3f20f25fb728a9a13784?d=identicon)[tstandiford](/maintainers/tstandiford)

---

Top Contributors

[![alexstandiford](https://avatars.githubusercontent.com/u/8210827?v=4)](https://github.com/alexstandiford "alexstandiford (22 commits)")[![malayladu](https://avatars.githubusercontent.com/u/708174?v=4)](https://github.com/malayladu "malayladu (4 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")

---

Tags

event-driveneventsframeworkobserver-patternphpphpnomadplatform-agnosticpub-sub

### Embed Badge

![Health badge](/badges/phpnomad-event/health.svg)

```
[![Health](https://phpackages.com/badges/phpnomad-event/health.svg)](https://phpackages.com/packages/phpnomad-event)
```

###  Alternatives

[laravel/dusk

Laravel Dusk provides simple end-to-end testing and browser automation.

1.9k39.6M299](/packages/laravel-dusk)[nineinchnick/edatatables

Grid widget for the Yii Framework, wrapper for the DataTables jQuery plugin

173.2k](/packages/nineinchnick-edatatables)[link-cloud/fast-hyperf

LinkCloud Fast Hyperf

241.2k1](/packages/link-cloud-fast-hyperf)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
