ThinkPHP软删除需在模型中启用SoftDelete trait并配置deleteTime字段,仅对模型实例或主键数组的delete()有效;批量操作须用destroy()并传true,查询默认过滤软删数据,恢复需通过withTrashed()查出后调用restore()。

ThinkPHP 软删除字段怎么配才生效
软删除不是加个 delete_time 字段就自动跑起来的,得让模型明确知道“这是软删字段”。默认情况下,ThinkPHP 的 SoftDelete trait 只认 delete_time,且要求字段类型是 datetime 或 timestamp(不能是 int 存时间戳,除非手动改配置)。
- 在模型类里 use
think\model\concern\SoftDelete,并加上use SoftDelete; - 确保数据库字段名和 trait 默认值一致:
delete_time;如果用别的名字(比如is_deleted),必须显式指定:protected $deleteTime = 'is_deleted'; - 如果字段是整型存时间戳,还得加:
protected $type = ['is_deleted' => 'integer'];,否则写入时会被当成字符串处理,查出来永远不为 null - 别忘了把该字段加到模型的
$autoWriteTimestamp和$updateTime无关——软删字段不走自动时间写入逻辑,它只在调用delete()时被赋值
批量删除多条记录时 delete() 为什么没触发软删
直接写 UserModel::where('status', 0)->delete() 是硬删,哪怕模型启用了软删除也不会拦截。ThinkPHP 的软删只对「单模型实例」或「主键数组」调用 delete() 有效,底层靠的是模型事件和 save() 行为,而不是 Db 查询构造器。
- 正确做法是先查出主键,再调用静态
destroy():UserModel::destroy([1,2,3], true)—— 第二个参数true表示强制走软删(即使没 use SoftDelete 也会尝试) - 或者用集合方式:
UserModel::where('status', 0)->select()->each(function ($item) { $item->delete(); });,但注意这会发起 N 次查询,大数据量慎用 - 千万别用
Db::name('user')->where(...)->delete(),这条路彻底绕过模型,软删完全失效 - 如果用
destroy()但没生效,检查是否传了false或漏了第二个参数,默认是false(硬删)
软删后查询为什么还是查不到数据
启用软删后,模型默认会自动过滤掉已软删的记录,也就是在所有 select 类查询末尾悄悄加上 AND delete_time IS NULL。这不是 bug,是设计行为,但容易让人误以为“数据丢了”。
- 想查包含软删数据?用
withTrashed():UserModel::withTrashed()->where('id', 5)->find() - 只想查已被软删的?用
onlyTrashed():UserModel::onlyTrashed()->select() - 注意:这些方法只对模型查询有效,
Db::name('user')写法不识别,也不会自动加条件 - 如果你在关联查询里发现子表数据莫名消失,大概率是关联模型也启用了软删,但父模型没调用
withTrashed(),导致关联条件匹配失败
restore() 恢复失败的几个典型原因
restore() 看似简单,实际失败往往是因为状态不匹配或调用方式不对。它不会报错,只是静默跳过,让人以为“点了没反应”。
- 只能对已软删的记录调用,即
delete_time IS NOT NULL;如果本来就是硬删过的,或delete_time是空字符串/0,restore()不会重置字段 - 别对查询构造器调用:
UserModel::where('id', 5)->restore()是无效的,必须是模型实例:UserModel::withTrashed()->find(5)->restore() - 使用
destroy()批量软删后,恢复也得逐条来,没有批量restore()方法;强行用update(['delete_time' => null])可以,但会跳过模型事件和验证 - 如果字段类型是
datetime,但数据库里存的是'0000-00-00 00:00:00',MySQL 8.0+ 默认不允许,restore()会因类型校验失败而静默失败
事情说清了就结束。软删本质是“标记 + 过滤”,不是魔法,每一步都依赖模型层介入;绕过模型的操作,软删就不存在。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










