PHPackages                             kode/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. [Queues &amp; Workers](/categories/queues)
4. /
5. kode/event

ActiveLibrary[Queues &amp; Workers](/categories/queues)

kode/event
==========

轻量级解耦事件编排库，支持事件派发、监听、订阅、异步事件、协程安全，可结合 kode/aop 做切面事件

1.5.0(2mo ago)06Apache-2.0PHPPHP &gt;=8.1

Since Apr 9Pushed 2mo agoCompare

[ Source](https://github.com/kodephp/event)[ Packagist](https://packagist.org/packages/kode/event)[ RSS](/packages/kode-event/feed)WikiDiscussions master Synced 2w ago

READMEChangelogDependencies (2)Versions (6)Used By (0)

kode/event 事件编排库
================

[](#kodeevent-事件编排库)

轻量级、解耦的事件系统，支持事件派发、监听、订阅、异步事件、协程安全，可结合 `kode/aop` 做切面事件。

特性
--

[](#特性)

- **事件派发** - 支持同步/异步事件派发
- **监听注册** - 支持优先级、通配符匹配
- **订阅者模式** - 通过订阅者集中管理监听器
- **属性声明** - PHP 8+ Attribute 声明式监听器
- **事件组** - 批量管理相关事件监听器
- **异步队列** - 支持 `kode/queue` 异步事件处理
- **协程安全** - 基于 `kode/context` 的协程上下文传递
- **AOP 切面** - 结合 `kode/aop` 实现切面事件
- **依赖注入** - 支持 `kode/di` 属性注入
- **PHP 8.5** - 支持新版本语言特性

环境要求
----

[](#环境要求)

- PHP &gt;= 8.1
- `kode/context` ^2.0（必须）

安装
--

[](#安装)

```
composer require kode/event
```

目录
--

[](#目录)

- [快速开始](#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B)
- [事件对象](#%E4%BA%8B%E4%BB%B6%E5%AF%B9%E8%B1%A1)
- [监听器](#%E7%9B%91%E5%90%AC%E5%99%A8)
- [订阅者](#%E8%AE%A2%E9%98%85%E8%80%85)
- [属性声明式监听](#%E5%B1%9E%E6%80%A7%E5%A3%B0%E6%98%8E%E5%BC%8F%E7%9B%91%E5%90%AC)
- [事件组](#%E4%BA%8B%E4%BB%B6%E7%BB%84)
- [事件构建器](#%E4%BA%8B%E4%BB%B6%E6%9E%84%E5%BB%BA%E5%99%A8)
- [抽象事件类](#%E6%8A%BD%E8%B1%A1%E4%BA%8B%E4%BB%B6%E7%B1%BB)
- [异常和验证](#%E5%BC%82%E5%B8%B8%E5%92%8C%E9%AA%8C%E8%AF%81)
- [PHP 8.5 特性](#php-85-%E7%89%B9%E6%80%A7)
- [事件助手](#%E4%BA%8B%E4%BB%B6%E5%8A%A9%E6%89%8B)
- [事件冒泡](#%E4%BA%8B%E4%BB%B6%E5%86%92%E6%B3%A1)
- [事件过滤器](#%E4%BA%8B%E4%BB%B6%E8%BF%87%E6%BB%A4%E5%99%A8)
- [延迟派发](#%E5%BB%B6%E8%BF%9F%E6%B4%BE%E5%8F%91)
- [事件追踪](#%E4%BA%8B%E4%BB%B6%E8%BF%BD%E8%B8%AA)
- [批量事件](#%E6%89%B9%E9%87%8F%E4%BA%8B%E4%BB%B6)
- [事件管道](#%E4%BA%8B%E4%BB%B6%E7%AE%A1%E9%81%93)
- [生命周期钩子](#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90)
- [不可变事件](#%E4%B8%8D%E5%8F%AF%E5%8F%98%E4%BA%8B%E4%BB%B6)
- [事件重放](#%E4%BA%8B%E4%BB%B6%E9%87%8D%E6%94%BE)
- [事件中间件](#%E4%BA%8B%E4%BB%B6%E4%B8%AD%E9%97%B4%E4%BB%B6)
- [事件验证](#%E4%BA%8B%E4%BB%B6%E9%AA%8C%E8%AF%81)
- [异步队列](#%E5%BC%82%E6%AD%A5%E9%98%9F%E5%88%97)
- [协程安全](#%E5%8D%8F%E7%A8%8B%E5%AE%89%E5%85%A8)
- [AOP 切面](#aop-%E5%88%87%E9%9D%A2)
- [依赖注入](#%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5)
- [门面模式](#%E9%97%A8%E9%9D%A2%E6%A8%A1%E5%BC%8F)
- [并行处理](#%E5%B9%B6%E8%A1%8C%E5%A4%84%E7%90%86)
- [API 参考](#api-%E5%8F%82%E8%80%83)

快速开始
----

[](#快速开始)

```
use Kode\Event\Dispatcher;
use Kode\Event\Event;

$dispatcher = new Dispatcher();

// 监听事件
$dispatcher->listen('user.created', function (Event $event) {
    echo "用户创建: " . $event->get('name') . "\n";
});

// 派发事件
$dispatcher->dispatch(new Event('user.created', ['name' => '张三']));
```

事件对象
----

[](#事件对象)

```
use Kode\Event\Event;

$event = new Event('order.paid', [
    'order_id' => 12345,
    'amount' => 99.99,
    'user_id' => 100,
]);

// 获取数据
$orderId = $event->get('order_id');
$amount = $event->get('amount', 0.0);

// 设置数据
$event->set('status', 'completed');

// 批量设置
$event->fill(['paid_at' => time(), 'payment_method' => 'alipay']);

// 检查数据
$event->has('order_id'); // true

// 停止传播
$event->stopPropagation();
$event->isPropagationStopped(); // true

// 时间戳
$event->getTimestamp();  // 纳秒时间戳
$event->getElapsed();    // 经过的时间（纳秒）
```

监听器
---

[](#监听器)

### Callable 监听器

[](#callable-监听器)

```
$dispatcher->listen('user.created', function (Event $event) {
    echo "用户创建\n";
});

// 带优先级（数值越大越先执行）
$dispatcher->listen('user.created', function (Event $event) {
    echo "高优先级\n";
}, priority: 100);

$dispatcher->listen('user.created', function (Event $event) {
    echo "低优先级\n";
}, priority: -100);
```

### 监听器类

[](#监听器类)

```
use Kode\Event\AbstractListener;
use Kode\Event\EventPriority;

class UserEventListener extends AbstractListener
{
    public function __construct()
    {
        parent::__construct('user.*', EventPriority::NORMAL->value);
    }

    protected function handleEvent(Event $event): void
    {
        echo "处理事件: {$event->getName()}\n";
    }
}

$dispatcher->listen('user.created', new UserEventListener());
```

### 监听器特性

[](#监听器特性)

```
use Kode\Event\EventListenerTrait;
use Kode\Event\EventPriority;

class UserListener
{
    use EventListenerTrait;

    public function __construct()
    {
        $this->setListenEvents(['user.*', 'order.*']);
        $this->setListenPriority(EventPriority::HIGH->value);
    }

    public function handle(Event $event): void
    {
        echo "处理事件: {$event->getName()}\n";
    }
}
```

### 事件派发 Trait

[](#事件派发-trait)

```
use Kode\Event\EventDispatcherTrait;

class UserService
{
    use EventDispatcherTrait;

    public function createUser(array $data): void
    {
        // 业务逻辑
        $this->emit('user.created', $data);
    }
}

$service = new UserService();
$service->on('user.created', function ($event) {
    echo "用户创建\n";
});
$service->createUser(['name' => '张三']);

// 一次性监听
$service->once('user.created', function ($event) {
    echo "只触发一次\n";
});
```

订阅者
---

[](#订阅者)

```
use Kode\Event\Dispatcher;
use Kode\Event\SubscriberInterface;

class UserSubscriber implements SubscriberInterface
{
    public function subscribe(Dispatcher $dispatcher): void
    {
        $dispatcher->listen('user.created', [$this, 'onCreated']);
        $dispatcher->listen('user.updated', [$this, 'onUpdated']);
        $dispatcher->listen('user.deleted', [$this, 'onDeleted']);
    }

    public function onCreated(Event $event): void
    {
        echo "用户创建: {$event->get('name')}\n";
    }

    public function onUpdated(Event $event): void
    {
        echo "用户更新: {$event->get('name')}\n";
    }

    public function onDeleted(Event $event): void
    {
        echo "用户删除: {$event->get('id')}\n";
    }
}

// 注册订阅者
$dispatcher->subscribe(new UserSubscriber());
```

属性声明式监听
-------

[](#属性声明式监听)

通过 PHP 8+ Attribute 声明式注册监听器。

### 基本用法

[](#基本用法)

```
use Kode\Event\Attribute\Listener;
use Kode\Event\Attribute\Priority;
use Kode\Event\Attribute\Subscriber;
use Kode\Event\AttributeListenerRegistry;

#[Subscriber]
class UserEventSubscriber
{
    #[Listener('user.created')]
    public function onUserCreated(Event $event): void
    {
        echo "用户创建: {$event->get('name')}\n";
    }

    #[Listener('user.updated')]
    public function onUserUpdated(Event $event): void
    {
        echo "用户更新: {$event->get('name')}\n";
    }

    #[Listener('user.deleted')]
    public function onUserDeleted(Event $event): void
    {
        echo "用户删除: {$event->get('id')}\n";
    }
}

// 创建注册器
$registry = new AttributeListenerRegistry($dispatcher);
$registry->register(new UserEventSubscriber());
```

### 多事件监听

[](#多事件监听)

```
#[Subscriber]
class OrderEventSubscriber
{
    #[Listener(['order.created', 'order.paid', 'order.completed'])]
    public function onOrderChanges(Event $event): void
    {
        echo "订单事件: {$event->getName()}\n";
    }
}
```

### 优先级设置

[](#优先级设置)

```
#[Subscriber]
class PrioritySubscriber
{
    #[Listener('app.start', priority: 100)]
    public function highPriority(): void
    {
        echo "高优先级\n";
    }

    #[Listener('app.start', priority: 0)]
    public function normalPriority(): void
    {
        echo "普通优先级\n";
    }

    #[Listener('app.start', priority: -100)]
    public function lowPriority(): void
    {
        echo "低优先级\n";
    }
}
```

### 批量注册

[](#批量注册)

```
$registry = new AttributeListenerRegistry($dispatcher);
$registry->registerMany([
    new UserEventSubscriber(),
    new OrderEventSubscriber(),
    new SystemSubscriber(),
]);
```

事件组
---

[](#事件组)

批量管理具有相同前缀/后缀的事件监听器。

### 基本用法

[](#基本用法-1)

```
use Kode\Event\EventGroup;

$group = EventGroup::prefix('user.');
$group->on('created', function (Event $e) { echo "创建\n"; });
$group->on('updated', function (Event $e) { echo "更新\n"; });
$group->on('deleted', function (Event $e) { echo "删除\n"; });

// 批量注册到调度器
$group->attach($dispatcher);

// 注销
$group->detach($dispatcher);
```

### 事件组工厂方法

[](#事件组工厂方法)

```
// 带前缀
$group = EventGroup::prefix('user.');

// 带后缀
$group = EventGroup::suffix('.event');

// 自定义前后缀
$group = EventGroup::create('order.', '.paid');

// 组合
$group = EventGroup::create('user.', '.admin');
$group->on('profile', $listener);  // 实际事件: user.profile.admin
```

### 一次性监听

[](#一次性监听)

```
$group = EventGroup::prefix('app.');
$group->once('start', function () {
    echo "应用启动\n";
});

$group->attach($dispatcher);
$dispatcher->dispatch(new Event('app.start'));  // 触发
$dispatcher->dispatch(new Event('app.start'));  // 不触发
```

事件构建器
-----

[](#事件构建器)

链式调用构建事件对象。

### 基本用法

[](#基本用法-2)

```
use Kode\Event\EventBuilder;

$event = EventBuilder::create('user.created')
    ->with('name', '张三')
    ->with('email', 'zhangsan@example.com')
    ->data(['age' => 25])  // 合并数据
    ->traceId('trace-123')
    ->meta('source', 'api')
    ->build();

$dispatcher->dispatch($event);
```

### 直接派发

[](#直接派发)

```
EventBuilder::create('user.created')
    ->with('name', '李四')
    ->with('email', 'lisi@example.com')
    ->dispatch($dispatcher);
```

抽象事件类
-----

[](#抽象事件类)

继承实现自定义事件类型。

### 基本用法

[](#基本用法-3)

```
use Kode\Event\AbstractEvent;

class UserCreatedEvent extends AbstractEvent
{
    protected function getEventName(): string
    {
        return 'user.created';
    }

    public function getUserId(): int
    {
        return $this->get('user_id');
    }

    public function getUserName(): string
    {
        return $this->get('name');
    }
}

$event = new UserCreatedEvent([
    'user_id' => 123,
    'name' => '张三',
]);

$dispatcher->dispatch($event);
```

### 抽象事件特性

[](#抽象事件特性)

```
// 自动实现 Stringable 接口
$event = new UserCreatedEvent(['user_id' => 1]);
echo $event;  // 输出: UserCreatedEvent(user.created)

// 自动实现 StoppableEventInterface
$event->stopPropagation();

// 支持事件名称动态获取
class OrderPaidEvent extends AbstractEvent
{
    public function __construct(private int $orderId)
    {
        parent::__construct(['order_id' => $orderId]);
    }

    protected function getEventName(): string
    {
        return 'order.paid';
    }
}
```

异常和验证
-----

[](#异常和验证)

### 内置异常

[](#内置异常)

```
use Kode\Event\Exception\InvalidEventException;
use Kode\Event\Exception\ListenerException;

throw InvalidEventException::emptyName();
// RuntimeException: 事件名称不能为空

throw InvalidEventException::invalidName('123.invalid');
// RuntimeException: 无效的事件名称: 123.invalid

throw ListenerException::notCallable('not callable');
// RuntimeException: 监听器必须可调用，当前类型: string
```

### 验证器

[](#验证器)

```
use Kode\Event\Validator;

// 验证事件名称
Validator::validateEventName('user.created');  // 通过
Validator::validateEventName('');  // 抛出异常
Validator::validateEventName('123.invalid');  // 抛出异常

// 验证监听器
Validator::validateListener(function() {});  // 通过
Validator::validateListener('not callable');  // 抛出异常

// 验证优先级
Validator::validatePriority(100);  // 通过
```

### 安全执行

[](#安全执行)

```
use Kode\Event\Validator;

// 安全调用
$result = Validator::safeCall(function() {
    return $maybeFails();
}, 'default');

// 安全执行监听器
$error = Validator::safeExecuteListener($listener, $event, stopOnError: true);
if ($error) {
    echo "监听器执行出错: " . $error->getMessage();
}
```

PHP 8.5 特性
----------

[](#php-85-特性)

### 版本检测

[](#版本检测)

```
use Kode\Event\Php85Features;

if (Php85Features::hasPipeOperator()) {
    // PHP 8.5+ 可以使用 |>
}

if (Php85Features::hasCloneWith()) {
    // PHP 8.5+ 可以使用 clone with 表达式
}
```

### Polyfill 方法

[](#polyfill-方法)

```
// 管道操作 polyfill（兼容 PHP < 8.5）
$result = Php85Features::pipe($value, fn($v) => $v * 2);
$result = Php85Features::pipeMany($value, [
    fn($v) => $v + 1,
    fn($v) => $v * 2,
    fn($v) => $v - 3,
]);
```

事件助手
----

[](#事件助手)

```
use Kode\Event\EventHelper;

// 检查有效名称
EventHelper::isValidName('user.created');  // true
EventHelper::isValidName('123.invalid');    // false

// 规范化名称
EventHelper::normalizeName(' User.Created ');  // 'user.created'

// 解析事件名称
$parsed = EventHelper::parseName('user.profile.updated');
// ['prefix' => 'user', 'name' => 'profile', 'suffix' => 'updated']

// 匹配模式
EventHelper::matchesPattern('user.created', 'user.*');   // true
EventHelper::matchesPattern('user.created', '*.created'); // true

// 创建事件
$event = EventHelper::create(Event::class, ['data' => 'value']);

// 批量创建
$events = EventHelper::createMany([
    'event.a' => ['data' => 1],
    'event.b' => ['data' => 2],
]);

// 获取 PHP 特性支持
$features = EventHelper::getPhpFeatures();
$features['enum'];       // true (PHP 8.1+)
$features['readonly'];   // true (PHP 8.1+)
$features['pipe_operator'];  // false (PHP 8.5+)
```

事件冒泡
----

[](#事件冒泡)

子事件自动冒泡到父事件。

```
use Kode\Event\EventBubbles;

$dispatcher = new Dispatcher();
$bubbles = new EventBubbles($dispatcher);

// 注册父子关系：user.created -> user.activity
$bubbles->registerParent('user.created', 'user.activity');
$bubbles->registerParent('user.updated', 'user.activity');

$dispatcher->listen('user.activity', function (Event $e) {
    echo "用户活动事件: {$e->getName()}\n";
});

$bubbles->bubble(new Event('user.created'));
// 输出: 用户活动事件: user.activity
```

### 批量注册

[](#批量注册-1)

```
$bubbles->registerParents([
    'user.created' => 'user.activity',
    'user.updated' => 'user.activity',
    'user.deleted' => 'user.activity',
]);
```

### 启用/禁用

[](#启用禁用)

```
$bubbles->disable();
$bubbles->enable();
$bubbles->isEnabled(); // false
```

事件过滤器
-----

[](#事件过滤器)

在事件派发前修改事件数据。

```
use Kode\Event\EventFilter;

$filter = new EventFilter();

$filter->add('user.created', function (Event $event) {
    $event->set('name', strtoupper($event->get('name')));
    $event->set('filtered', true);
    return $event;
}, priority: 10);

$event = new Event('user.created', ['name' => 'test']);
$filtered = $filter->filter($event);

echo $filtered->get('name'); // TEST
echo $filtered->get('filtered'); // true
```

### 移除过滤器

[](#移除过滤器)

```
$myFilter = function (Event $event) { return $event; };
$filter->add('test', $myFilter);
$filter->remove('test', $myFilter);
```

延迟派发
----

[](#延迟派发)

延迟一段时间后派发事件。

```
use Kode\Event\DeferredDispatcher;

$dispatcher = new Dispatcher();
$deferred = new DeferredDispatcher($dispatcher);

// 延迟 5 秒派发
$jobId = $deferred->defer('user.created', ['name' => '张三'], delay: 5);

// 取消延迟事件
$deferred->cancel($jobId);

// 处理到期的延迟事件
$deferred->process();

// 处理所有延迟事件
$deferred->processAll();

// 检查待处理数量
$deferred->count();
```

事件追踪
----

[](#事件追踪)

追踪事件派发的性能和时间。

```
use Kode\Event\EventTracer;

$tracer = new EventTracer($dispatcher);
$tracer->enable();

$event = new Event('user.created', ['data' => 'value']);

$tracer->trace($event, function () use ($event, $dispatcher) {
    $dispatcher->dispatch($event);
});

// 获取追踪信息
$trace = $tracer->getRecentTraces(1)[0];
$trace['event'];        // 'user.created'
$trace['duration'];     // 纳秒
$trace['listenerCount']; // 监听器数量
$trace['data'];         // ['data' => 'value']

// 获取所有追踪
$tracer->getAllTraces();

// 清空追踪记录
$tracer->clear();
```

批量事件
----

[](#批量事件)

批量构建和派发事件。

```
use Kode\Event\BatchEventBuilder;

$dispatcher = new Dispatcher();
$batch = BatchEventBuilder::batch($dispatcher);

// 批量派发
$batch->create('user.created')
      ->create('user.updated')
      ->create('order.created')
      ->dispatch();

// 带前缀后缀
$batch->prefix('app.')
      ->suffix('.event')
      ->create('start')
      ->create('stop')
      ->dispatch();

// 带默认数据
$batch->defaults(['source' => 'batch', 'timestamp' => time()])
      ->with('user.created', ['name' => 'test'])
      ->dispatch();

// 仅构建不派发
$events = $batch->create('user.created')
                ->create('user.updated')
                ->build();
```

事件管道
----

[](#事件管道)

链式变换事件数据，支持 PHP 8.5 管道操作符。

```
use Kode\Event\EventPipeline;

$event = new Event('user.created', ['name' => 'test']);
$pipeline = EventPipeline::create($event);

$result = $pipeline
    ->pipe(fn($e) => $e->set('piped', true))
    ->pipe(fn($e) => $e->set('step', 1))
    ->execute();
```

### 过滤器

[](#过滤器)

```
$pipeline->filter(fn($e) => $e->get('value') > 0)
        ->pipe(fn($e) => $e->set('passed', true));
```

### 变换映射

[](#变换映射)

```
$pipeline->map(fn($e) => $e->set('mapped', true));
```

### 调试

[](#调试)

```
$pipeline->tap(fn($e) => var_dump($e->getData()));
```

### 停止管道

[](#停止管道)

```
$pipeline->stop();
```

### 链式执行回调

[](#链式执行回调)

```
$result = $pipeline
    ->pipe(fn($e) => $e->set('done', true))
    ->then(fn($e) => $e->get('value') * 2);
```

### 直接派发

[](#直接派发-1)

```
$pipeline->pipe(fn($e) => $e->set('enhanced', true))
         ->dispatch($dispatcher);
```

生命周期钩子
------

[](#生命周期钩子)

在事件派发的各个阶段插入自定义逻辑。

```
use Kode\Event\EventHooks;

$hooks = new EventHooks();

$hooks->before(function (Event $event) {
    $event->set('before_dispatch', time());
    return $event;
}, priority: 100);

$hooks->after(function (Event $event) {
    echo "事件已派发: {$event->getName()}\n";
});

$hooks->error(function (Event $event, \Throwable $e) {
    echo "派发错误: {$e->getMessage()}\n";
});

// 触发钩子
$event = new Event('test');
$event = $hooks->triggerBefore($event);
$dispatcher->dispatch($event);
$hooks->triggerAfter($event);
```

### 移除钩子

[](#移除钩子)

```
$myHook = function (Event $event) { return $event; };
$hooks->before($myHook);
$hooks->removeBefore($myHook);
```

### 清空钩子

[](#清空钩子)

```
$hooks->clear('before'); // 仅清空 before
$hooks->clear();         // 清空所有
```

不可变事件
-----

[](#不可变事件)

使用 PHP 8.1 readonly 属性的不可变事件对象。

```
use Kode\Event\ImmutableEvent;

$event = ImmutableEvent::create('user.created', ['name' => 'test']);

// 只读属性
$event->name;        // 'user.created'
$event->data;        // ['name' => 'test']
$event->propagationStopped; // false

// 创建新实例（不修改原对象）
$newEvent = $event->with('age', 25);
$newEvent = $event->withData(['extra' => 'data']);
$newEvent = $event->withStopped();

// 从普通事件转换
$immutable = ImmutableEvent::fromEvent($event);
```

事件重放
----

[](#事件重放)

记录和重放事件序列。

```
use Kode\Event\EventReplay;

$dispatcher = new Dispatcher();
$replay = new EventReplay($dispatcher);

// 记录事件
$replay->record(new Event('user.created', ['id' => 1]));
$replay->record(new Event('user.updated', ['id' => 1]));

// 重放所有
$replay->replay();

// 重放指定范围
$replay->replay(from: 0, count: 5);

// 反向重放
$replay->replayReverse();

// 重放直到特定事件
$replay->replayUntil('user.deleted');

// 条件重放
$replay->replayIf(fn($e) => $e->has('id'));

// 导出/导入
$exported = $replay->export();
$imported = EventReplay::import($exported);
```

事件中间件
-----

[](#事件中间件)

在事件派发过程中插入中间件处理。

```
use Kode\Event\EventMiddleware;
use Kode\Event\LoggingMiddleware;
use Kode\Event\ValidationMiddleware;

$middleware = new EventMiddleware();

// 添加中间件
$middleware->add(function ($event, $next) {
    echo "前置处理\n";
    $result = $next($event);
    echo "后置处理\n";
    return $result;
}, priority: 10);

// 处理事件
$middleware->process($event, fn($e) => $dispatcher->dispatch($e));
```

### 日志中间件

[](#日志中间件)

```
$logging = new LoggingMiddleware();
$logging->handle($event, fn($e) => $dispatcher->dispatch($e));
```

### 验证中间件

[](#验证中间件)

```
$validation = new ValidationMiddleware();

$validation->addRule('user.created', fn($e) => $e->has('user_id'));
$validation->addRule('user.created', fn($e) => is_int($e->get('user_id')));

$validation->handle($event, fn($e) => $dispatcher->dispatch($e));
```

事件验证
----

[](#事件验证)

使用 Schema 定义和验证事件结构。

```
use Kode\Event\EventSchema;
use Kode\Event\EventSchemaRegistry;

$schema = EventSchema::create('user.created')
    ->required('user_id', 'int')
    ->required('name', 'string')
    ->optional('email', 'string')
    ->validate(fn($e) => $e->get('user_id') > 0);

$event = new Event('user.created', [
    'user_id' => 123,
    'name' => '张三',
]);

if ($schema->validateEvent($event)) {
    $dispatcher->dispatch($event);
}
```

### Schema 注册表

[](#schema-注册表)

```
$registry = new EventSchemaRegistry();

$registry->register(EventSchema::create('user.created')
    ->required('user_id', 'int'));

$registry->register(EventSchema::create('order.paid')
    ->required('order_id', 'int')
    ->required('amount', 'numeric'));

// 验证事件
$registry->validate($event);

// 批量验证
$registry->validateMany([$event1, $event2]);
```

事件名称常量
------

[](#事件名称常量)

```
use Kode\Event\EventNames;

EventNames::USER_CREATED;    // 'user.created'
EventNames::USER_UPDATED;    // 'user.updated'
EventNames::ORDER_PAID;      // 'order.paid'
EventNames::ORDER_COMPLETED; // 'order.completed'

$dispatcher->listen(EventNames::USER_CREATED, $listener);
```

事件优先级
-----

[](#事件优先级)

```
use Kode\Event\EventPriority;

EventPriority::CRITICAL->value;   // 200
EventPriority::HIGH->value;     // 100
EventPriority::ELEVATED->value; // 50
EventPriority::NORMAL->value;   // 0
EventPriority::LOW->value;     // -100
EventPriority::DEFERRED->value; // -200
```

通配符匹配
-----

[](#通配符匹配)

```
$dispatcher->listen('user.*', function (Event $event) {
    echo "所有用户事件: {$event->getName()}\n";
});

$dispatcher->listen('*.created', function (Event $event) {
    echo "所有创建事件\n";
});

$dispatcher->listen('*.*', function (Event $event) {
    echo "所有事件\n";
});
```

异步队列
----

[](#异步队列)

```
composer require kode/queue
```

```
use Kode\Event\Queue\AsyncEvent;
use Kode\Event\Queue\QueueDispatcher;
use Kode\Event\Queue\Integration\KodeQueueDriver;
use Kode\Queue\Factory;

$queue = Factory::create([
    'default' => 'redis',
    'connections' => [
        'redis' => ['host' => '127.0.0.1', 'port' => 6379]
    ]
]);

$driver = new KodeQueueDriver($queue);
$dispatcher = new Dispatcher();
$queueDispatcher = new QueueDispatcher($driver, $dispatcher);

// 派发异步事件
$jobId = $queueDispatcher->enqueue('user.created', ['name' => '张三']);

// 延迟派发
$jobId = $queueDispatcher->enqueue('user.created', ['name' => '李四'], delay: 60);

// 消费队列
while ($queueDispatcher->process()) {
    // 处理事件
}
```

协程安全
----

[](#协程安全)

```
composer require kode/runtime
```

```
use Kode\Event\Coroutine\ContextStorage;
use Kode\Runtime\Runtime;

$context = new ContextStorage();
$context->setEventTraceId('trace-' . uniqid());

$dispatcher->listen('user.created', function (Event $event) {
    $traceId = Context::get('event.trace_id');
    echo "Trace: $traceId\n";
});

// 协程派发
Runtime::async(fn() => $dispatcher->dispatch(new Event('user.created', ['name' => '王五'])));
Runtime::wait();

// 上下文隔离
$result = $context->run(function () {
    Context::set('event.name', 'isolated');
    return Context::get('event.name');
});
```

AOP 切面
------

[](#aop-切面)

```
composer require kode/aop
```

```
use Kode\Event\Aop\AspectEventDispatcher;

$dispatcher = new AspectEventDispatcher();

$dispatcher->registerAspect('user.*', function (Event $event) {
    echo "前置: {$event->getName()}\n";
}, priority: 100);

$dispatcher->registerAspect('user.*', function (Event $event) {
    echo "后置: {$event->getName()}\n";
}, priority: -100);

$dispatcher->dispatch(new Event('user.created'));
```

依赖注入
----

[](#依赖注入)

```
composer require kode/di
```

```
use Kode\DI\Attributes\Inject;
use Kode\DI\Attributes\Singleton;

#[Singleton]
class UserService
{
    #[Inject]
    private Dispatcher $dispatcher;

    public function createUser(array $data): void
    {
        $this->dispatcher->dispatch(new Event('user.created', $data));
    }
}
```

门面模式
----

[](#门面模式)

```
composer require kode/facade
```

```
use Kode\Facade\Facade;

abstract class EventFacade extends Facade
{
    protected static function id(): string
    {
        return 'event.dispatcher';
    }
}

EventFacade::listen('user.created', function ($event) {
    echo "用户创建\n";
});

EventFacade::dispatch(new Event('user.created', ['name' => '赵六']));
```

并行处理
----

[](#并行处理)

```
composer require kode/parallel
```

```
use Kode\Parallel\Runtime\Runtime;
use Kode\Parallel\Channel\Channel;

$runtime = new Runtime();
$channel = Channel::make('events');
$dispatcher = new Dispatcher();

$runtime->run(fn() => $channel->send(new Event('user.created', ['name' => '用户1'])));
$runtime->run(fn() => $channel->send(new Event('user.created', ['name' => '用户2'])));

$runtime->run(function () use ($channel, $dispatcher) {
    while ($event = $channel->recv()) {
        $dispatcher->dispatch($event);
    }
});

$runtime->close();
```

API 参考
------

[](#api-参考)

### Event

[](#event)

方法说明`getName()`获取事件名称`get(string $key, $default)`获取事件数据`set(string $key, $value)`设置事件数据`fill(array $data)`批量设置数据`has(string $key)`检查键是否存在`stopPropagation()`停止事件传播`isPropagationStopped()`检查是否已停止`getTimestamp()`获取创建时间戳`getElapsed()`获取经过的时间### Dispatcher

[](#dispatcher)

方法说明`listen(string $event, $listener, int $priority)`注册监听器`unlisten(string $event, $listener)`注销监听器`subscribe(SubscriberInterface $subscriber)`注册订阅者`dispatch(Event|string $event, array $data)`派发事件`dispatchMany(Event ...$events)`批量派发`hasListeners(string $event)`检查是否有监听器`getListeners(string $event)`获取监听器列表`clear(?string $event)`清空监听器### EventGroup

[](#eventgroup)

方法说明`on(string $event, callable $listener, int $priority)`注册监听器`once(string $event, callable $listener)`注册一次性监听器`off(string $event)`注销监听器`attach(Dispatcher $dispatcher)`批量注册到调度器`detach(Dispatcher $dispatcher)`从调度器注销### EventBuilder

[](#eventbuilder)

方法说明`create(string $name)`创建构建器`with(string $key, $value)`添加数据`data(array $data)`批量添加数据`traceId(string $id)`设置追踪ID`meta(string $key, $value)`添加元数据`build()`构建事件对象`dispatch(Dispatcher $dispatcher)`直接派发### AttributeListenerRegistry

[](#attributelistenerregistry)

方法说明`register(object|string $subscriber)`注册订阅者`registerMany(array $subscribers)`批量注册`getDispatcher()`获取调度器### Validator

[](#validator)

方法说明`validateEventName(string $name)`验证事件名称`validateListener($listener)`验证监听器`validatePriority(int $priority)`验证优先级`safeCall(callable $callback, $default)`安全调用`safeExecuteListener($listener, Event $event)`安全执行监听器### EventPipeline

[](#eventpipeline)

方法说明`create(Event $event)`创建管道`pipe(callable $transform)`添加变换步骤`filter(callable $predicate)`添加过滤条件`map(callable $mapper)`添加映射变换`tap(callable $callback)`添加调试回调`stop()`停止管道`execute()`执行管道`then(callable $callback)`执行并回调`dispatch(Dispatcher $dispatcher)`执行并派发### EventHooks

[](#eventhooks)

方法说明`before(callable $hook, int $priority)`添加前置钩子`after(callable $hook, int $priority)`添加后置钩子`error(callable $hook, int $priority)`添加错误钩子`removeBefore(callable $hook)`移除前置钩子`removeAfter(callable $hook)`移除后置钩子`removeError(callable $hook)`移除错误钩子`triggerBefore(Event $event)`触发前置钩子`triggerAfter(Event $event)`触发后置钩子`triggerError(Event $event, Throwable $e)`触发错误钩子`clear(?string $type)`清空钩子项目结构
----

[](#项目结构)

```
src/
├── Attribute/                        # PHP 8+ 属性
│   ├── Listener.php                # 监听器属性
│   ├── Priority.php                 # 优先级属性
│   └── Subscriber.php              # 订阅者属性
├── Exception/                       # 异常
│   └── EventException.php          # 事件异常
├── Event.php                        # 基础事件类
├── AbstractEvent.php               # 抽象事件类
├── AbstractListener.php            # 监听器抽象类
├── AttributeListenerRegistry.php   # 属性监听器注册器
├── BatchEventBuilder.php           # 批量事件构建器
├── DeferredDispatcher.php          # 延迟派发调度器
├── Dispatcher.php                   # 事件调度器
├── EventBubbles.php                # 事件冒泡
├── EventBuilder.php                # 事件构建器
├── EventDispatcherTrait.php       # 事件调度特性
├── EventFilter.php                 # 事件过滤器
├── EventGroup.php                  # 事件组
├── EventHelper.php                 # 事件助手
├── EventHooks.php                  # 生命周期钩子
├── EventInterceptorInterface.php   # 拦截器接口
├── EventListenerTrait.php         # 监听器特性
├── EventMiddleware.php            # 事件中间件
├── EventNames.php                 # 事件名称常量
├── EventPipeline.php              # 事件管道
├── EventPriority.php              # 事件优先级枚举
├── EventReplay.php               # 事件重放
├── EventSchema.php               # 事件验证
├── EventTracer.php                # 事件追踪器
├── ImmutableEvent.php            # 不可变事件
├── InterceptorRegistry.php        # 拦截器注册表
├── ListenerInterface.php          # 监听器接口
├── Php85Features.php              # PHP 8.5 特性
├── Queue/
│   ├── QueueDriverInterface.php
│   ├── AsyncEvent.php
│   ├── QueueDispatcher.php
│   └── Integration/
│       └── KodeQueueDriver.php
├── Coroutine/
│   ├── CoroutineContextInterface.php
│   └── ContextStorage.php
├── Aop/
│   └── AspectEventDispatcher.php
└── Validator.php                    # 验证器

```

许可证
---

[](#许可证)

Apache-2.0

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance85

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

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

Total

5

Last Release

79d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/230488886?v=4)[kodephp](/maintainers/kodephp)[@kodephp](https://github.com/kodephp)

---

Top Contributors

[![mofeier](https://avatars.githubusercontent.com/u/16829186?v=4)](https://github.com/mofeier "mofeier (7 commits)")

---

Tags

eventasynccoroutinedispatchsubscribeaspect oriented

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[amphp/amp

A non-blocking concurrency framework for PHP applications.

4.4k130.2M402](/packages/amphp-amp)[revolt/event-loop

Rock-solid event loop for concurrent PHP applications.

92550.1M206](/packages/revolt-event-loop)[icicleio/icicle

Icicle is a PHP library for writing asynchronous code using synchronous coding techniques.

1.1k152.2k14](/packages/icicleio-icicle)[sabre/event

sabre/event is a library for lightweight event-based programming

35228.5M26](/packages/sabre-event)[recoil/recoil

Asynchronous coroutines for PHP 7.

79062.4k7](/packages/recoil-recoil)[recoil/react

Integrate Recoil with ReactPHP.

32283.0k12](/packages/recoil-react)

PHPackages © 2026

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