<p>ThinkPHP 6 中仅 before_* 模型事件(如 before_write、before_update、before_delete)返回 false 可中断操作;Db 类操作不触发模型事件;观察者模式中 creating/updating/deleting 方法同理支持中断;软删除时 before_delete 可阻止软删,硬删需用 forceDeleting 或 isForce() 判断。</p>

在 ThinkPHP 6 中,模型事件本身不支持“取消操作”(比如像中间件里 return false 中断流程),但可以通过 前置事件返回 false 实现逻辑中断——这是唯一官方支持的拦截方式。
before_* 类事件可中断写入或删除
只有以 before_ 开头的模型事件(如 before_write、before_update、before_delete)支持返回 false 来中止后续操作。其他事件(如 after_write、saved)纯属通知性质,无法影响执行流程。
-
before_write:在save()或insert()执行前触发,返回false可阻止数据写入 -
before_update:仅在更新时触发($model->isUpdate() === true),返回false可跳过更新 -
before_delete:在delete()或destroy()前触发,返回false可阻止删除
注意:Db 类操作完全不走模型事件
用 Db::name('user')->where(...)->delete() 或 update() 等方式操作数据库,不会触发任何模型事件,自然也无法中断。要确保中断生效,必须严格使用模型方法:
- ✅ 正确:
UserModel::find(123)->delete()或UserModel::destroy(123) - ❌ 无效:
Db::name('user')->where('id', 123)->delete()
观察者模式下同样适用中断逻辑
TP6.1+ 推荐用观察者类(Observer),其中 creating、updating、deleting 方法也支持返回 false 中断:
立即学习“PHP免费学习笔记(深入)”;
- 在
app\observe\UserObserver.php中定义:public function updating(User $model) { if ($model->status === 0) return false; } - 该方法返回
false后,框架将不再执行后续的 SQL 更新 - 注意命名必须是小驼峰格式(
updating),不是onUpdate或afterUpdate
软删除场景下的特殊处理
若启用了 SoftDelete,调用 delete() 实际是软删(设 delete_time),此时 before_delete 仍会触发,返回 false 可同时阻止软删;但若想只阻止硬删(force()->delete()),需监听 forceDeleting(观察者)或在 before_delete 中判断 $model->isForce()(需自行扩展逻辑)。



















