ThinkPHP6.0软删除需模型引入SoftDelete trait、声明$deleteTime字段、启用$useSoftDelete=true;数据库delete_time字段须允许NULL且无默认值;删除/查询/恢复必须通过模型方法操作,不可用Db类直删。

在 ThinkPHP6.0 中启用软删除,核心是让数据“标记删除”而非物理清除,同时保证查询默认不显示已删记录、支持手动恢复。这不是加个 trait 就自动生效的开关,必须模型、字段、调用三者严格对齐。
模型配置:trait + 字段声明 + 显式启用
模型类需明确引入 SoftDelete trait,并设置关键属性:
- 必须写 use think\model\concern\SoftDelete; 和 use SoftDelete;
- 声明 protected $deleteTime = 'delete_time';(字段名要和数据库一致)
- 务必设置 protected $useSoftDelete = true;(TP6.0 低版本不设会退化为硬删)
- 若字段类型是 BIGINT 时间戳,还需加 protected $type = ['delete_time' => 'integer'];
数据库字段:允许 NULL,禁用默认值
对应表中必须存在 delete_time 字段(或你自定义的字段名),且满足:
- 类型为 DATETIME / TIMESTAMP / BIGINT UNSIGNED 三者之一
- 必须允许 NULL(NOT NULL 会导致软删写入失败且静默返回 false)
- 不能设 DEFAULT CURRENT_TIMESTAMP 或 ON UPDATE(否则新插入记录就带值,被误判为已删除)
删除与查询:走模型方法,注意调用姿势
所有操作必须通过模型发起,Db 类直删会绕过全部逻辑:
立即学习“PHP免费学习笔记(深入)”;
-
软删除:用
UserModel::destroy(123)或$user->delete()—— 写入 delete_time,不删行 -
真实删除:必须加
force参数,如UserModel::destroy(456, true)或$user->force()->delete() -
查全部(含已删):用
UserModel::withTrashed()->select(),且必须放在链式调用最前面 -
只查已删:用
UserModel::onlyTrashed()->select()
恢复数据:先定位,再判空,最后检查结果
restore() 是实例方法,不能链式批量调用:
- 先用
UserModel::onlyTrashed()->find(789)获取软删实例 - 判断是否非 null:
if ($user) { $user->restore(); } - 检查返回值:
false === $user->restore()表示失败,需排查字段 NULL 权限、模型 soft_delete 配置、数据库当前 delete_time 值 - 批量恢复不能写
onlyTrashed()->where()->restore(),应改用update(['delete_time' => null])或分块调用each->restore()



















