核心原因是未走模型层——调用db类或原生sql不会触发模型事件;必须使用user::create()、save()或模型insert()等orm方法,且需在模型中显式声明protected static $event = ['before_write', 'after_write']。

ThinkPHP 6.0 中监听数据库新增操作失败,**核心原因不是事件没写对,而是根本没走到模型层**——你调用的不是模型方法,而是 Db 查询构造器或原生 SQL,模型事件自然不会触发。
新增操作必须走模型 save() 或 create() 才会触发事件
TP6 的模型事件(如 before_insert、after_insert、after_write)仅在 ORM 模型方法中生效,与 Db 类完全无关:
- ✅ 有效触发:
User::create($data)、(new User())->save($data)、User::insert($data)(注意:TP6.0+ 的insert()是模型静态方法,会触发after_write) - ❌ 完全不触发:
Db::name('user')->insert($data)、Db::table('user')->insert($data)、Db::execute('INSERT INTO ...')
确认你监听的是正确的事件名
TP6.0 没有独立的 after_insert 静态事件(该事件在 TP5 中存在,TP6 已统一为 after_write)。常用且覆盖新增的模型事件是:
-
before_write:写入前(含 insert/update),可修改数据或拦截 -
after_write:写入后(含 insert/update),适合记录日志、推送消息 -
before_insert和after_insert在 TP6.0 中 不被原生支持,除非你手动扩展模型基类并注册对应钩子
检查模型是否正确声明了事件监听
仅在 app/model/User.php 中写 use SoftDelete; 或定义字段是不够的。必须显式声明要监听的事件:
- 在模型类中添加:
protected static $event = ['before_write', 'after_write']; - 确保该模型继承自
think\Model(而非直接 extends Model) - 若使用自定义基类,请确认基类未覆盖或屏蔽
$event属性
验证事件是否真正注册并执行
别依赖页面 Trace 或控制器日志判断,模型事件在命令行、队列、API 请求中均可能运行。稳妥验证方式:
- 在监听逻辑开头加一行:
file_put_contents(runtime/log/event_test.log', date('Y-m-d H:i:s') . " after_write triggered\n", FILE_APPEND); - 执行新增操作后,直接查看该文件是否有追加内容
- 若无记录,说明事件根本没触发 → 回退检查是否用了
Db::insert()或模型未加载
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











