PHPackages                             jasny/event-dispatcher - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. jasny/event-dispatcher

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

jasny/event-dispatcher
======================

PSR-14 compatible event dispatcher that's easy to use

v1.0.1(6y ago)21.1k↓50%1[1 issues](https://github.com/jasny/event-dispatcher/issues)1MITPHPPHP &gt;=7.2.0

Since Oct 27Pushed 6y agoCompare

[ Source](https://github.com/jasny/event-dispatcher)[ Packagist](https://packagist.org/packages/jasny/event-dispatcher)[ RSS](/packages/jasny-event-dispatcher/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (5)Versions (8)Used By (1)

Jasny Event Dispatcher
======================

[](#jasny-event-dispatcher)

[![Build Status](https://camo.githubusercontent.com/75c7cdf1ab0b932c9be577087b7228621c64a9097c24715e97a9b4dd6d33fa70/68747470733a2f2f7472617669732d63692e6f72672f6a61736e792f6576656e742d646973706174636865722e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/jasny/event-dispatcher)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/525abfca7fa1d0d1c3d13a8ee0274d46a54f84d91160a37c5e65386a5ec23fd4/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6a61736e792f6576656e742d646973706174636865722f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/jasny/event-dispatcher/?branch=master)[![Code Coverage](https://camo.githubusercontent.com/46bf4d304577b5de8f6bff0eecec6e0396b33f66068e65d472ea4d4e2ada3995/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6a61736e792f6576656e742d646973706174636865722f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/jasny/event-dispatcher/?branch=master)[![Packagist Stable Version](https://camo.githubusercontent.com/46f617d37001212fe3b121a6c6af32536df3cd984fb2d134b8bbe0b5b27d7998/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6a61736e792f6576656e742d646973706174636865722e737667)](https://packagist.org/packages/jasny/event-dispatcher)[![Packagist License](https://camo.githubusercontent.com/6a861208242a73e9c12433a89c3204dfaa0e9f1b056f26d59c0840c70c69e095/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6a61736e792f6576656e742d646973706174636865722e737667)](https://packagist.org/packages/jasny/event-dispatcher)

A [PSR-14](https://www.php-fig.org/psr/psr-14/) compatible event dispatcher that's easy to use.

Event dispatching is a common and well-tested mechanism to allow developers to inject logic into an application easily and consistently.

The PSR only requires determining events based on their class name, any other method is optional. Libraries should only depend on the specification and not on the implementation, therefore each event type must have it's own class.

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

[](#installation)

```
composer require jasny/event-dispatcher

```

Usage
-----

[](#usage)

#### 1. Define your own event classes

[](#1-define-your-own-event-classes)

```
namespace App\Event;

/**
 * Base class for all events in this application.
 */
abstract class Base
{
    /** @var object */
    protected $emitter;

    /** @var mixed */
    protected $payload;

    public function __construct(object $emitter, $payload = null)
    {
        $this->emitter = $emitter;
        $this->payload = $payload;
    }

    final public function getEmitter(): object
    {
        return $this->emitter;
    }

    public function setPayload($payload): void
    {
        $this->payload = $payload;
    }

    public function getPayload()
    {
        return $this->payload;
    }
}

/**
 * Called before an entity is saved to the database.
 */
class BeforeSave extends Base
{}

/**
 * Called when an entity is casted to json.
 */
class ToJson extends Base
{}
```

#### 2. Create listeners

[](#2-create-listeners)

```
use App\Event;
use Jasny\EventDispatcher\EventDispatcher;
use Jasny\EventDispatcher\ListenerProvider;

$listener = (new ListenerProvider)
    ->withListener(function(Event\BeforeSave $event): void {
        $entity = $event->getEmitter();
        $payload = $event->getPayload();

        $payload['bio'] = $payload['bio'] ?? ($entity->name . " just arrived");
        $event->setPayload($payload);
    })
    ->withListener(function(Event\ToJson $event): void {
        $payload = $event->getPayload();

        unset($payload['password']);
        $event->setPayload($payload);
    });
```

The provider will use the type hint of the first argument of the lister to determine if the listener applies to the given event.

Listeners are executed in the order they're registered to the provider. It's not possible to prepend existing listeners.

#### 3. Create the dispatcher

[](#3-create-the-dispatcher)

```
$dispatcher = new EventDispatcher($listener);
```

#### 4. Dispatch an event

[](#4-dispatch-an-event)

Typically a subject will hold its own dispatcher and trigger events.

```
use App\Event;
use Jasny\EventDispatcher\EventDispatcher;

class Foo implements JsonSerializable
{
    /**
     * @var EventDispatcher
     */
    protected $eventDispatcher;

    // ...

    public function jsonSerialize()
    {
        $payload = get_object_vars($this);

        return $this->eventDispatcher->dispatch(new Event\ToJson($this, $payload));
    }
}
```

### Add listener

[](#add-listener)

`ListenerProvider` and `EventDispatcher` are immutable services. Methods `withListener` and `withListenerProvider` resp will create a modified copy of each service.

```
use App\Event;

$newListener = $dispatcher->getListener()
    ->off(function(Event\BeforeSave $event): void {
        $payload = $event->getPayload();

        $payload['bio'] = strtr($payload['bio'], $payload['email'], '***@***.***');
        $event->setPayload($payload);
    });

$newDispatcher = $dispatcher->withListenerProvider($newListener);
```

### Stoppable events

[](#stoppable-events)

The event must implement the `StoppableEventInterface` of PSR-14.

```
namespace App\Event;

use Psr\EventDispatcher\StoppableEventInterface;

/**
 * Called before an entity is saved to the database.
 */
class BeforeSave implememnts StoppableEventInterface
{
    // ...

    public function stopPropagation(): void
    {
        $this->propagationStopped = true;
    }

    public function isPropagationStopped(): bool
    {
        return $this->propagationStopped;
    }
}
```

```
use App\Event;
use Jasny\EventDispatcher\EventDispatcher;
use Jasny\EventDispatcher\ListenerProvider;

$listener = (new ListenerProvider)
    ->on(function(Event\BeforeSave $event): void {
        $entity = $event->getEmitter();

        if (!$entity->isReady()) {
            $event->stopPropagation();
        }
    });

$dispatcher = new EventDispatcher($listener);
```

### Listener namespace

[](#listener-namespace)

Listeners may be registered to the provider under a namespace.

```
use App\Event;
use Jasny\EventDispatcher\EventDispatcher;
use Jasny\EventDispatcher\ListenerProvider;

$listener = (new ListenerProvider)
    ->withListenerInNs('censor', function(Event\BeforeSave $event): void {
        $payload = $event->getPayload();

        $payload['bio'] = strtr($payload['bio'], $payload['email'], '***@***.***');
        $event->setPayload($payload);
    });
    ->withListenerInNs('censor.json', function(Event $event): void {
        $payload = $event->getPayload();

        unset($payload['password']);
        $event->setPayload($payload);
    });
```

This can be used to remove all listeners within the namespace and all subnamespaces.

```
$newListeners = $dispatcher->getListenerProvider()->withoutNs('censor');
```

*This example removes both the listener in the `censor` and `censor.json` namespace.*

#### Namespace wildcard

[](#namespace-wildcard)

You may use a wildcard to specify all subnamespaces regardless of the parent

```
$newListeners = $dispatcher->getListenerProvider()->withoutNs('*.json');
```

*This example removes the listener in the `censor.json` namespace.*

###  Health Score

29

—

LowBetter than 59% of packages

Maintenance10

Infrequent updates — may be unmaintained

Popularity22

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity61

Established project with proven stability

 Bus Factor1

Top contributor holds 100% 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 ~36 days

Recently: every ~10 days

Total

7

Last Release

2541d ago

Major Versions

v0.1.1 → v1.0.02019-04-23

v0.1.2 → v1.0.12019-06-03

PHP version history (4 changes)v0.1.0PHP &gt;=7.1.0

v0.1.1PHP ~7.2.0

v1.0.0PHP &gt;=7.2.0

v0.1.2PHP ^7.2.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/3379a93d51305df325df9045e1a8b205d195e4e8c01312dff53a000ee79002eb?d=identicon)[jasny](/maintainers/jasny)

---

Top Contributors

[![jasny](https://avatars.githubusercontent.com/u/100821?v=4)](https://github.com/jasny "jasny (13 commits)")

---

Tags

event-dispatcherphp7psr-14

### Embed Badge

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

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

###  Alternatives

[symfony/event-dispatcher-contracts

Generic abstractions related to dispatching event

3.4k756.5M424](/packages/symfony-event-dispatcher-contracts)[league/event

Event package

1.6k141.6M184](/packages/league-event)[phpro/soap-client

A general purpose SoapClient library

8885.6M46](/packages/phpro-soap-client)[yohang/finite

A simple PHP Finite State Machine

1.3k3.5M10](/packages/yohang-finite)[mcp/sdk

Model Context Protocol SDK for Client and Server applications in PHP

1.4k423.9k30](/packages/mcp-sdk)[cognesy/instructor-php

The complete AI toolkit for PHP: unified LLM API, structured outputs, agents, and coding agent control

310107.9k1](/packages/cognesy-instructor-php)

PHPackages © 2026

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