Hyperf事件系统基于PSR-14,核心是定义事件类、注册监听器、触发分发;事件类应轻量final,监听器实现ListenerInterface并用@Listener注解或配置注册,支持同步、异步及延迟触发。

Hyperf 的事件系统基于 PSR-14 标准,轻量、解耦、支持异步监听,是实现模块间松耦合通信的核心机制。用好它,关键在三点:定义清晰的事件类、注册合适的监听器、按需触发与分发。
定义自定义事件类
事件本质是一个普通 PHP 类,通常不带逻辑,只承载数据。建议放在 app/Event 目录下,继承 Hyperf\Event\Event(非必须,但利于识别)。
- 事件类应为 final,属性设为 public 或提供 getter 方法,便于监听器读取
- 避免在构造函数中做耗时操作,事件实例化应轻量
- 示例:
<?php
declare(strict_types=1);
namespace App\Event;
use Hyperf\Event\Event;
final class UserRegistered extends Event
{
public function __construct(public int $userId, public string $email)
{
// 不建议在这里调 API 或查库
}
}
编写并注册事件监听器
监听器是实现 ListenerInterface 的类,负责响应特定事件。注册方式有两种:
-
自动扫描注册:在监听器类上加
@Listener注解,并指定监听的事件类,如:
@Listener(UserRegistered::class)
Hyperf 启动时会自动收集并绑定 -
手动配置注册:在
config/autoload/listeners.php中返回数组映射,适合动态或条件注册场景:
return [
App\Listener\UserRegisteredListener::class => [
App\Event\UserRegistered::class,
],
]; - 监听器方法名固定为
listen(),接收事件实例作为唯一参数
触发事件的三种常用方式
事件分发由 Hyperf\Event\EventDispatcher 完成,框架已注入容器,可直接使用。
-
同步触发(默认):在业务逻辑中直接 dispatch,所有监听器按注册顺序依次执行
$this->event->dispatch(new UserRegistered($id, $email)); -
异步触发(推荐耗时操作):配合
Hyperf\AsyncQueue或协程,避免阻塞主流程
go(function () use ($event) {
$this->event->dispatch($event);
}); -
延迟触发(需 Queue 组件):适用于定时通知、积分延后发放等场景
use Hyperf\AsyncQueue\Job;
$this->queue->push(new class($event) extends Job {
public function handle() {
$this->container->get(EventDispatcher::class)->dispatch($this->event);
}
});
进阶技巧与注意事项
实际项目中容易忽略但影响稳定性的细节:
- 监听器内不要抛出未捕获异常,否则会中断后续监听器执行;建议用 try-catch 包裹核心逻辑
- 避免在监听器中修改原事件对象(尤其引用传递场景),保持事件不可变性更安全
- 高频事件(如日志、埋点)可考虑批量聚合或采样,防止打满 EventLoop
- 调试时可通过
php bin/hyperf.php event:listen查看已注册的监听关系









