本文目录导读:

在ThinkPHP框架中,事件订阅者和事件组是事件系统的重要组成部分,让我详细介绍它们的用法:
基础概念
事件(Event)
// 创建事件类
namespace app\event;
class UserLogin
{
public $user;
public function __construct($user)
{
$this->user = $user;
}
}
监听器(Listener)
// 创建监听器
namespace app\listener;
class SendLoginNotify
{
public function handle(UserLogin $event)
{
// 处理登录通知
echo "用户 {$event->user->name} 登录成功";
}
}
事件订阅者(Event Subscriber)
事件订阅者允许在一个类中监听多个事件:
namespace app\subscriber;
class UserSubscriber
{
/**
* 定义订阅的事件
* @return array
*/
public function subscribe()
{
return [
'UserLogin' => 'onUserLogin',
'UserLogout' => 'onUserLogout',
'UserRegister' => ['onUserRegister', 'onUserRegisterSubscribe'],
];
}
// 处理用户登录
public function onUserLogin($event)
{
// 记录登录日志
Log::info('用户登录: ' . $event->user->name);
}
// 处理用户退出
public function onUserLogout($event)
{
// 清除会话等操作
Cache::delete('user_' . $event->user->id);
}
// 处理用户注册
public function onUserRegister($event)
{
// 发送欢迎邮件
}
// 注册后的额外操作
public function onUserRegisterSubscribe($event)
{
// 订阅默认服务
}
}
事件组(Event Groups)
事件组是多个相关事件的集合,便于管理和监听:
// 定义事件组配置
// config/event.php
return [
'bind' => [
'AppInit' => 'app\event\AppInit',
'HttpRun' => 'app\event\HttpRun',
'HttpEnd' => 'app\event\HttpEnd',
'UserLogin' => 'app\event\UserLogin',
'UserLogout' => 'app\event\UserLogout',
],
'listen' => [
'AppInit' => [],
'HttpRun' => [],
'HttpEnd' => [],
'UserLogin' => [
'app\listener\SendLoginNotify',
'app\listener\RecordLoginHistory',
],
'UserLogout' => [
'app\listener\ClearUserCache',
],
],
'subscribe' => [
'app\subscriber\UserSubscriber',
'app\subscriber\OrderSubscriber',
],
];
实际应用示例
订单事件组示例
// 创建订单事件组
namespace app\event\group;
class OrderEvent
{
// 订单创建
public function onOrderCreate($order)
{
// 记录订单日志
Log::info("订单创建成功: " . $order->order_no);
}
// 订单支付
public function onOrderPay($order)
{
// 更新订单状态
$order->status = 1;
$order->save();
// 发送支付成功通知
event('SendMessage', $order);
}
// 订单取消
public function onOrderCancel($order)
{
// 恢复库存
// 记录日志
Log::info("订单取消: " . $order->order_no);
}
// 订单完成
public function onOrderComplete($order)
{
// 发送评价提醒
// 更新用户积分
}
}
多模块事件订阅
namespace app\common\subscriber;
class SystemSubscriber
{
public function subscribe()
{
return [
'AppInit' => ['onAppInit', 'checkSystemStatus'],
'HttpEnd' => 'onHttpEnd',
'LogWrite' => 'onLogWrite',
];
}
public function onAppInit()
{
// 系统初始化检查
$this->checkSystemStatus();
}
public function checkSystemStatus()
{
// 检查系统运行状态
if (config('app.debug') === false) {
// 生产环境检查逻辑
}
}
public function onHttpEnd()
{
// 记录请求耗时
$time = microtime(true) - THINK_START;
Log::info('请求耗时: ' . $time . 's');
}
public function onLogWrite()
{
// 日志写入后的操作
}
}
事件触发
// 在控制器或服务中触发事件
class UserController extends BaseController
{
public function login()
{
$user = User::find($id);
// 触发用户登录事件
event('UserLogin', $user);
// 或使用事件类
event(new UserLogin($user));
// 触发事件组
event('OrderEvent', $order, 'onOrderCreate');
}
}
注册订阅者
// 方式1:配置文件
// config/event.php
'subscribe' => [
'app\subscriber\UserSubscriber',
'app\common\subscriber\SystemSubscriber',
],
// 方式2:动态注册(在服务提供者中)
// app/provider/EventService.php
use think\facade\Event;
class EventService extends Service
{
public function boot()
{
Event::subscribe('app\subscriber\UserSubscriber');
Event::subscribe('app\common\subscriber\SystemSubscriber');
}
}
高级用法
事件优先级
// 支持监听器优先级(数值越大越先执行)
'listen' => [
'UserLogin' => [
[ 'app\listener\RecordLoginHistory', 10 ],
[ 'app\listener\SendLoginNotify', 5 ],
],
],
条件监听
// 带条件的监听器
class OrderListener
{
public function handle($event)
{
if ($event->amount > 1000) {
// 大额订单特殊处理
event('BigAmountOrder', $event);
}
}
}
通过合理使用事件订阅者和事件组,可以让你的代码更加模块化,降低耦合度,提高代码的可维护性。