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

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

inhere/event
============

event manager library of the php

v1.1.3(7y ago)282002MITPHPPHP &gt;7.1.0

Since Dec 9Pushed 7y ago1 watchersCompare

[ Source](https://github.com/inhere/php-event-manager)[ Packagist](https://packagist.org/packages/inhere/event)[ Docs](https://github.com/inhere/php-event-manager)[ RSS](/packages/inhere-event/feed)WikiDiscussions master Synced 4d ago

READMEChangelog (4)DependenciesVersions (8)Used By (0)

Event Dispatcher
================

[](#event-dispatcher)

[![License](https://camo.githubusercontent.com/45076ada16344d091377acc1ad01bfeb1db0362494c66bfe001e63ee4c51f092/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f696e686572652f6576656e742e7376673f7374796c653d666c61742d737175617265)](LICENSE)[![Php Version](https://camo.githubusercontent.com/d90f27811e67c164d7cb22e93d0a6020a77beed41f0790469d90188fd42c57f5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d2533453d372e312e302d627269676874677265656e2e7376673f6d61784167653d32353932303030)](https://packagist.org/packages/inhere/event)[![Latest Stable Version](https://camo.githubusercontent.com/deaf48dc6248271c894a82ba61dc4a953a8c63c339c8bc9ebc472d8514d4722e/687474703a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f696e686572652f6576656e742e737667)](https://packagist.org/packages/inhere/event)

> **[EN README](./README_en.md)**

简洁, 功能完善的事件管理调度实现

- 实现自 [Psr 14](https://github.com/php-fig/fig-standards/blob/master/proposed/event-dispatcher.md) - 事件调度器
- 支持对一个事件添加多个监听器
- 支持设置事件优先级
- 支持快速的事件组注册
- 支持根据事件名称来快速的对事件组监听
    - eg 触发 `app.run`, `app.end` 都将同时会触发 `app.*` 事件
- 支持通配符事件的监听

项目地址
----

[](#项目地址)

- **github**

安装
--

[](#安装)

- composer 命令

```
composer require inhere/event
```

- composer.json

```
{
    "require": {
        "inhere/event": "dev-master"
    }
}
```

### 事件调度器

[](#事件调度器)

事件调度器, 也可称之为事件管理器。事件的注册、监听器注册、调度(触发)都是由它管理的。

```
use Inhere\Event\EventManager;

$em = new EventManager();
```

事件监听器
-----

[](#事件监听器)

监听器允许是:

1. function 函数
2. 一个闭包
3. 一个监听器类(可以有多种方式)

### 1. function

[](#1-function)

```
// ...

$em->attach(Mailer::EVENT_MESSAGE_SENT, 'my_function');
```

### 2. 闭包

[](#2-闭包)

```
// ...

$em->attach(Mailer::EVENT_MESSAGE_SENT, function(Event $event) {
    // $message = $event->message;
    // ... some logic
});
```

### 3. 监听器类(有多种方式)

[](#3-监听器类有多种方式)

- 类里面存在跟事件相同名称的方法

> 此种方式可以在类里面写多个事件的处理方法

```
class ExamListener1
{
    public function messageSent(EventInterface $event)
    {
        echo "handle the event {$event->getName()}\n";
    }
}
```

- 一个类(含有 `__invoke` 方法)

> 此时这个类对象就相当于一个闭包

```
class ExamListener2
{
    public function __invoke(EventInterface $event)
    {
        echo "handle the event {$event->getName()}\n";
    }
}
```

- 实现接口 `EventHandlerInterface`

触发时会自动调用 `handle()` 方法。

```
class ExamHandler implements EventHandlerInterface
{
    /**
     * @param EventInterface $event
     * @return mixed
     */
    public function handle(EventInterface $event)
    {
        // TODO: Implement handle() method.
    }
}
```

- 实现接口 `EventSubscriberInterface`

可以在一个类里面自定义监听多个事件

```
/**
 * Class EnumGroupListener
 * @package Inhere\Event\Examples
 */
class EnumGroupListener implements EventSubscriberInterface
{
    const TEST_EVENT = 'test';
    const POST_EVENT = 'post';

    /**
     * 配置事件与对应的处理方法
     * @return array
     */
    public static function getSubscribedEvents(): array
    {
        return [
            self::TEST_EVENT => 'onTest',
            self::POST_EVENT => ['onPost', ListenerPriority::LOW], // 还可以配置优先级
        ];
    }

    public function onTest(EventInterface $event)
    {
        $pos = __METHOD__;
        echo "handle the event {$event->getName()} on the: $pos\n";
    }

    public function onPost(EventInterface $event)
    {
        $pos = __METHOD__;
        echo "handle the event {$event->getName()} on the: $pos\n";
    }
}
```

快速使用
----

[](#快速使用)

### 1. 绑定事件触发

[](#1-绑定事件触发)

```
// a pre-defined event
class MessageEvent extends Event
{
    // append property ...
    public $message;
}

// in the business
class Mailer
{
    use EventManagerAwareTrait;

    const EVENT_MESSAGE_SENT = 'messageSent';

    public function send($message)
    {
        // ...发送 $message 的逻辑...

        $event = new MessageEvent(self::EVENT_MESSAGE_SENT);
        $event->message = $message;

        // 事件触发
        $this->eventManager->trigger($event);
    }
}
```

### 2. 触发事件

[](#2-触发事件)

```
$em = new EventManager();

// 绑定事件
$em->attach(Mailer::EVENT_MESSAGE_SENT, 'exam_handler');
$em->attach(Mailer::EVENT_MESSAGE_SENT, function (EventInterface $event)
{
    $pos = __METHOD__;
    echo "handle the event {$event->getName()} on the: $pos\n";
});

// 这里给它设置了更高的优先级
$em->attach(Mailer::EVENT_MESSAGE_SENT, new ExamListener1(), 10);
$em->attach(Mailer::EVENT_MESSAGE_SENT, new ExamListener2());
$em->attach(Mailer::EVENT_MESSAGE_SENT, new ExamHandler());

$mailer = new Mailer();
$mailer->setEventManager($em);

// 执行，将会触发事件
$mailer->send('hello, world!');
```

### 3. 运行示例

[](#3-运行示例)

完整的实例代码在 `examples/demo.php` 中。

运行: `php examples/demo.php`

输出：

```
$ php examples/exam.php
handle the event 'messageSent' on the: ExamListener1::messageSent // 更高优先级的先调用
handle the event 'messageSent' on the: exam_handler
handle the event 'messageSent' on the: {closure}
handle the event 'messageSent' on the: ExamListener2::__invoke
handle the event 'messageSent' on the: Inhere\Event\Examples\ExamHandler::handle

```

一组事件的监听器
--------

[](#一组事件的监听器)

除了一些特殊的事件外，在一个应用中，大多数事件是有关联的，此时我们就可以对事件进行分组，方便识别和管理使用。

- **事件分组** 推荐将相关的事件，在名称设计上进行分组

例如：

```
// 模型相关：
model.insert
model.update
model.delete

// DB相关：
db.connect
db.disconnect
db.query

// 应用相关：
app.start
app.run
app.stop

```

### 1. 一个简单的示例应用类

[](#1-一个简单的示例应用类)

```
/**
 * Class App
 * @package Inhere\Event\Examples
 */
class App
{
    use EventManagerAwareTrait;

    const ON_START = 'app.start';
    const ON_STOP = 'app.stop';
    const ON_BEFORE_REQUEST = 'app.beforeRequest';
    const ON_AFTER_REQUEST = 'app.afterRequest';

    public function __construct(EventManager $em)
    {
        $this->setEventManager($em);

        $this->eventManager->trigger(new Event(self::ON_START, [
            'key' => 'val'
        ]));
    }

    public function run()
    {
        $sleep = 0;
        $this->eventManager->trigger(self::ON_BEFORE_REQUEST);

        echo 'request handling ';
        while ($sleep eventManager->trigger(self::ON_AFTER_REQUEST);
    }

    public function __destruct()
    {
        $this->eventManager->trigger(new Event(self::ON_STOP, [
            'key1' => 'val1'
        ]));
    }
}
```

### 2. 此应用的监听器类

[](#2-此应用的监听器类)

将每个事件的监听器写一个类，显得有些麻烦。我们可以只写一个类用里面不同的方法来处理不同的事件。

- 方式一： **类里面存在跟事件名称相同的方法**(`app.start` -&gt; `start()`)

> 这种方式简单快捷，但是有一定的限制 - 事件名与方法的名称必须相同。

```
/**
 * Class AppListener
 * @package Inhere\Event\Examples
 */
class AppListener
{
    public function start(EventInterface $event)
    {
        $pos = __METHOD__;
        echo "handle the event {$event->getName()} on the: $pos\n";
    }

    public function beforeRequest(EventInterface $event)
    {
        $pos = __METHOD__;
        echo "handle the event {$event->getName()} on the: $pos\n";
    }

    public function afterRequest(EventInterface $event)
    {
        $pos = __METHOD__;
        echo "handle the event {$event->getName()} on the: $pos\n";
    }

    public function stop(EventInterface $event)
    {
        $pos = __METHOD__;
        echo "handle the event {$event->getName()} on the: $pos\n";
    }
}
```

- 方式二：实现接口 `EventSubscriberInterface`

有时候我们并不想将处理方法定义成事件名称一样，想自定义。

此时我们可以实现接口 `EventSubscriberInterface`，通过里面的 `getSubscribedEvents()` 来自定义事件和对应的处理方法

> 运行示例请看 `examples/enum-group.php`

```
/**
 * Class EnumGroupListener
 * @package Inhere\Event\Examples
 */
class EnumGroupListener implements EventSubscriberInterface
{
    const TEST_EVENT = 'test';
    const POST_EVENT = 'post';

    /**
     * 配置事件与对应的处理方法
     * @return array
     */
    public static function getSubscribedEvents(): array
    {
        return [
            self::TEST_EVENT => 'onTest',
            self::POST_EVENT => ['onPost', ListenerPriority::LOW], // 还可以配置优先级
        ];
    }

    public function onTest(EventInterface $event)
    {
        $pos = __METHOD__;
        echo "handle the event {$event->getName()} on the: $pos\n";
    }

    public function onPost(EventInterface $event)
    {
        $pos = __METHOD__;
        echo "handle the event {$event->getName()} on the: $pos\n";
    }
}
```

### 3. 添加监听

[](#3-添加监听)

```
// 这里使用 方式一
$em = new EventManager();

// register a group listener
$em->attach('app', new AppListener());

// create app
$app = new App($em);

// run.
$app->run();
```

### 4. 运行示例

[](#4-运行示例)

完整的示例代码在 `examples/named-group.php` 中。

运行: `php examples/named-group.php`

输出：

```
$ php examples/named-group.php
handle the event 'app.start' on the: Inhere\Event\Examples\AppListener::start
handle the event 'app.beforeRequest' on the: Inhere\Event\Examples\AppListener::beforeRequest
request handling ....
handle the event 'app.afterRequest' on the: Inhere\Event\Examples\AppListener::afterRequest
handle the event 'app.stop' on the: Inhere\Event\Examples\AppListener::stop

```

事件通配符 `*`
---------

[](#事件通配符-)

支持使用事件通配符 `*` 对一组相关的事件进行监听, 分两种。

1. `*` 全局的事件通配符。直接对 `*` 添加监听器(`$em->attach('*', 'global_listener')`), 此时所有触发的事件都会被此监听器接收到。
2. `{prefix}.*` 指定分组事件的监听。eg `$em->attach('db.*', 'db_listener')`, 此时所有触发的以 `db.` 为前缀的事件(eg `db.query` `db.connect`)都会被此监听器接收到。

> 当然，你在事件到达监听器前停止了本次事件的传播`$event->stopPropagation(true);`，就不会被后面的监听器接收到了。

示例，在上面的组事件监听器改下，添加一个 `app.*` 的事件监听。

```
// AppListener 新增一个方法
class AppListener
{
    // ...

    public function allEvent(EventInterface $event)
    {
        $pos = __METHOD__;
        echo "handle the event '{$event->getName()}' on the: $pos\n";
    }
}

// ...

$em = new EventManager();

$groupListener = new AppListener();

// register a group listener
$em->attach('app', $groupListener);

// all `app.` prefix events will be handled by `AppListener::allEvent()`
$em->attach('app.*', [$groupListener, 'allEvent']);

// create app
$app = new App($em);

// run.
$app->run();
```

### 运行示例

[](#运行示例)

运行: `php examples/named-group.php`输出：(*可以看到每个事件都经过了`AppListener::allEvent()`的处理*)

```
$ php examples/named-group.php
handle the event 'app.start' on the: Inhere\Event\Examples\AppListener::start
handle the event 'app.start' on the: Inhere\Event\Examples\AppListener::allEvent
handle the event 'app.beforeRequest' on the: Inhere\Event\Examples\AppListener::beforeRequest
handle the event 'app.beforeRequest' on the: Inhere\Event\Examples\AppListener::allEvent
request handling ....
handle the event 'app.afterRequest' on the: Inhere\Event\Examples\AppListener::afterRequest
handle the event 'app.afterRequest' on the: Inhere\Event\Examples\AppListener::allEvent
handle the event 'app.stop' on the: Inhere\Event\Examples\AppListener::stop
handle the event 'app.stop' on the: Inhere\Event\Examples\AppListener::allEvent

```

事件对象
----

[](#事件对象)

事件对象 - 装载了在触发事件时相关的上下文信息，用户自定义的。

### 预先创建一个事件

[](#预先创建一个事件)

- 直接简单的使用类 `Event`

```
$myEvent = new Event('name', 'target', [ 'some params ...' ]);
```

- 使用继承了 `Event` 的子类

这样你可以追加自定义数据

```
// create event class
class MessageEvent extends Event
{
    protected $name = 'messageSent';

    // append property ...
    public $message;
}
```

License
-------

[](#license)

MIT

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity21

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity63

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 ~81 days

Recently: every ~100 days

Total

6

Last Release

2673d ago

PHP version history (2 changes)v1.0.0PHP &gt;=7.0.0

v1.1.2PHP &gt;7.1.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/d23e1decaf354e8f36a7ad61128865dc78dd63336c2d023d79aa3ff8ba2a05ff?d=identicon)[inhere](/maintainers/inhere)

---

Top Contributors

[![inhere](https://avatars.githubusercontent.com/u/5302062?v=4)](https://github.com/inhere "inhere (38 commits)")

---

Tags

eventevent-managementpsr-14eventlibraryevent dispatcher

### Embed Badge

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

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

###  Alternatives

[doctrine/event-manager

The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.

6.1k501.1M115](/packages/doctrine-event-manager)

PHPackages © 2026

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