Appearance
概述
EBAOZU 系统采用 ThinkPHP 8.0 的事件驱动机制(Event Driven Architecture),通过事件(Event)与监听器(Listener)将复杂业务解耦。在订单生命周期、用户行为触发、支付成功通知等场景中广泛使用事件机制。
核心配置与目录结构
目录结构
app/
├── event.php # 系统全局事件与监听器映射定义文件
└── listener/ # 事件监听器实现目录
├── order/ # 订单生命周期监听器
│ ├── Create.php # 订单创建后监听
│ ├── Pay.php # 订单支付成功监听
│ ├── Delivery.php # 订单发货监听
│ ├── Take.php # 订单确认收货监听
│ ├── Refund.php # 订单退款监听
│ └── ...
├── user/ # 用户行为监听器
│ ├── Register.php # 用户注册监听
│ ├── Login.php # 用户登录监听
│ └── ...
├── pay/ # 支付回调监听器
│ ├── PayNotifyListener.php # 支付异步通知处理
│ └── ...
└── product/ # 商品状态变更监听器事件定义与注册
在 app/event.php 中配置事件标识与监听器类映射:
php
// app/event.php
return [
'bind' => [
// 绑定事件标识到事件类(可选)
],
'listen' => [
// 订单创建事件
'order.create' => [
\app\listener\order\Create::class,
],
// 订单支付成功事件
'order.pay' => [
\app\listener\order\Pay::class,
],
// 订单发货事件
'order.delivery' => [
\app\listener\order\Delivery::class,
],
// 用户登录事件
'user.login' => [
\app\listener\user\Login::class,
],
// 支付回调事件
'pay.notify' => [
\app\listener\pay\PayNotifyListener::class,
],
],
'subscribe' => [
// 事件订阅类
],
];事件触发与监听实现
触发事件
在业务 Service 或 Controller 中使用助手函数 event() 或 Event::trigger() 触发事件:
php
use think\facade\Event;
// 方式一:使用助手函数
event('order.create', [$orderInfo, $cartInfo]);
// 方式二:使用 Event 门面
Event::trigger('order.pay', [$orderId, $orderInfo]);
// 方式三:直至某个监听器返回非空结果才停止(用于中断控制)
$res = Event::until('pay.notify', [$notifyData, 'wechat']);编写事件监听器
监听器实现统一的 handle() 方法:
php
<?php
namespace app\listener\order;
use crmeb\interfaces\ListenerInterface;
use app\jobs\order\OrderCreateAfterJob;
use app\jobs\order\OrderStatusJob;
class Create implements ListenerInterface
{
/**
* 事件处理方法
* @param mixed $event 触发事件时传递的参数数组
*/
public function handle($event): void
{
[$orderInfo, $cartInfo] = $event;
$orderId = (int)$orderInfo['id'];
// 1. 投递异步队列任务处理耗时逻辑(如清理购物车、分配分销等)
OrderCreateAfterJob::dispatchDo('delCart', [$orderInfo['uid'], $orderInfo['cart_id']]);
// 2. 记录订单状态流转日志
OrderStatusJob::dispatch([$orderId, 'create', '订单创建成功']);
}
}二次开发扩展指南
新增业务事件完整流程
- 定义监听器:在
app/listener/下创建新的监听类(如app/listener/custom/CustomAction.php)。 - 注册事件:在
app/event.php的listen数组中添加对应的映射关系。 - 在业务中触发:在主流程合适位置调用
event('custom.event_name', [$params])。 - 耗时操作入队:监听器内部若涉及发短信、第三方接口调用、大量数据统计等耗时操作,务必投递到
app/jobs/异步队列中执行,避免阻塞 HTTP 响应主线程。