tp5 使用 hook 机制而非事件系统,需在 app/common.php 或 app/tags.php 中用 \think\hook::add() 提前注册监听器,再通过 \think\hook::listen() 触发;不可在控制器或模型中动态注册,且钩子名必须被实际调用才生效。

TP5 里没有 event() 函数,别直接调用
直接在控制器或模型里写 event('user_login') 或 Event::trigger(),一定会报 Fatal error: Uncaught Error: Call to undefined function event() 或 Class not found: think\facade\Event。TP5 根本不提供这两个东西——它用的是 \think\Hook,不是事件系统,是钩子(Hook)机制。
\think\Hook::add() 必须在初始化早期注册
注册监听器不是“哪里需要就在哪里写”,而是必须赶在框架真正开始运行前完成,否则 \think\Hook::listen() 找不到任何行为。
- 最稳妥位置是
app/common.php或app/tags.php(如果配合行为使用) - 注册语法:
\think\Hook::add('user_login', function($user) { echo "欢迎 {$user['name']}"; }); - 支持类方法数组:
\think\Hook::add('user_login', ['app\hook\LoginLogger', 'log']);,要求方法为 public - 别在控制器方法里注册——每次请求都重复 add,导致监听器执行多次;也别在模型
init()里注册,模型可能还没加载完
自定义钩子名必须被实际调用,否则静默失效
\think\Hook::add('my_tag', ...) 只是往内存数组塞数据,不等于它会被执行。只有当某处代码明确写了 \think\Hook::listen('my_tag', $params),且该行代码真正在请求生命周期中被执行,行为才会触发。
一款AI开发辅助工具,主要用于从 AI 编程会话日志(Clawdbot、Claude Code、Codex)中提取对话记录。该功能用于在用户要求导出提示词历史、会话日志或 `.jsonl` 格式的会话文件时使用,适合需要提升相关任务效率的用户。
- 框架内置标签位如
app_init、view_filter是安全的,因为它们在App::run()内部被调用 - 你在控制器里手动写
\think\Hook::listen('my_tag', $data),但my_tag没在tags.php配置过,也不会报错,只是什么也不做 - 想验证是否生效?在行为类
run()方法里加exit('hook triggered');,页面中断才说明进去了
别把 TP5 Hook 当 TP6 Event 用
TP6 已彻底删除 \think\Hook 类,vendor 目录下找不到 Hook.php。强行复制 TP5 的 Hook 文件到 TP6 项目中,会因容器、自动加载、上下文缺失而 fatal error 或静默失败。
如果你正从 TP5 升级,记住:TP5 的 \think\Hook::add() + \think\Hook::listen() 和 TP6 的 event() / Event::trigger() 是两套互不兼容的机制,不能混用,也不能靠“改个名字”迁移。
真正容易被忽略的是:TP5 的钩子不校验参数类型、不提示错误、不记录日志——失效时既不抛异常也不输出 warning,只能靠你主动加调试断点或 exit 验证执行路径。










