thinkphp中通过全局事件监听器自动记录用户关键操作日志:定义user_operation事件、注册useroperationlogger监听器、在登录/删除订单/修改密码等场景触发事件,避免侵入业务逻辑。

在ThinkPHP项目中需要自动记录用户关键操作(如登录、删除订单、修改密码)的日志,又不想在每个控制器方法里手动写日志代码,避免侵入业务逻辑、降低可维护性。
注册全局事件监听器
在应用初始化阶段绑定监听器,确保所有请求都经过统一日志入口。打开 app/event.php 文件,在 return 数组中添加 'user_operation' 事件定义:
【必须存在该键名,否则后续触发无效】 'user_operation' => [],
接着在 app/provider.php 中注册监听器类:将 app\listener\UserOperationLogger::class 加入 providers 数组末尾。
创建日志监听器类
执行命令行生成监听器:php think make:listener UserOperationLogger。
打开生成的 app/listener/UserOperationLogger.php,修改 handle 方法,接收 $event 参数并提取用户ID与操作描述:
if (auth()->check()) { $userId = auth()->id(); $action = $event['action'] ?? 'unknown'; $ip = request()->ip(); Db::name('user_log')->insert(['user_id' => $userId, 'action' => $action, 'ip' => $ip, 'created_at' => date('Y-m-d H:i:s')]); }
注意:这里不校验 $event 结构,【若传入空 action 字符串,数据库字段将存入 'unknown',无法回溯真实行为】。
在业务逻辑中触发日志事件
方法一:控制器内主动触发
在用户登录成功后,调用 event('user_operation', ['action' => 'login']);。
方法二:模型事件钩子联动
在 app/model/Order.php 的 delete() 方法末尾添加 event('user_operation', ['action' => 'delete_order', 'order_id' => $this->id]);。
方法三:中间件拦截敏感路由
新建中间件 app/middleware/LogUserAction.php,在 handle 方法中匹配 URL 路径:当 request()->url() 包含 '/admin/user/password' 且请求方式为 POST 时,执行 event('user_operation', ['action' => 'change_password']);。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











