ThinkPHP 8 的事件系统基于观察者模式 ,它的核心作用是实现代码的解耦 和异步处理。简单来说,当你的业务代码(比如用户登录成功)执行到某个节点时,可以"触发"一个事件,而具体的后续处理逻辑(比如发送登录通知、记录登录日志)则交给"监听器"去完成。
在 ThinkPHP 8 中,使用事件主要分为以下四个步骤:
1. 快速生成事件和监听器
ThinkPHP 提供了便捷的命令行工具来生成标准的类文件:
- 生成事件类:
php think make:event UserLogin - 生成监听器类:
php think make:listener SendNotification
2. 定义事件类(Event)
事件类主要负责承载和传递数据。你可以把业务中需要用到的数据通过构造函数传进去。
php
// app/event/UserLogin.php
namespace app\event;
class UserLogin
{
public $user;
public $loginTime;
public function __construct($user)
{
$this->user = $user;
$this->loginTime = time();
}
}
- 定义监听器类(Listener)
监听器类中包含一个 handle 方法,当对应的事件被触发时,这个方法会自动执行。
php
// app/listener/SendNotification.php
namespace app\listener;
use app\event\UserLogin;
class SendNotification
{
// handle 方法的参数会自动注入触发的事件对象
public function handle(UserLogin $event)
{
// 获取事件传递过来的数据,执行具体的业务逻辑
$userName = $event->user['name'];
// 例如:发送登录成功的邮件或短信通知
echo "发送登录通知给用户: " . $userName;
}
}
4. 绑定事件与监听器
在 app/event.php 配置文件中,将事件和监听器关联起来。最常用的方式是使用 listen 进行配置:
php
// app/event.php
return [
'listen' => [
// 当 UserLogin 事件被触发时,执行 SendNotification 监听器
'UserLogin' => [
'app\listener\SendNotification',
// 一个事件可以绑定多个监听器,按顺序执行
// 'app\listener\RecordLoginLog',
],
],
];
5. 在业务代码中触发事件
在你的控制器或业务逻辑层,当用户登录成功后,使用 event() 助手函数(或 Event::trigger() 门面)来触发事件:
php
// 假设在控制器的登录方法中
public function login()
{
// ... 执行账号密码验证等登录逻辑 ...
$user = ['id' => 1, 'name' => '张三'];
// 登录成功后,触发 UserLogin 事件,并将用户数据传递出去
event(new \app\event\UserLogin($user));
return '登录成功';
}
💡 进阶技巧与常用场景
- 处理高耗时任务(异步处理) :
ThinkPHP 内置了一个非常实用的系统事件叫HttpEnd。这个事件会在HTTP 响应完全发送给客户端之后 才触发。你可以把发送邮件、同步数据到 Elasticsearch 等耗时操作放在HttpEnd的监听器里,这样用户就不需要等待这些操作完成,能极大地提升页面的响应速度。 - 事件订阅(Subscribe) :
如果你有一个类需要监听很多个相关的事件(比如用户模块需要监听"用户注册"、"用户登录"、"用户注销"),可以使用"事件订阅者"来集中管理,避免event.php配置文件变得过于冗长。