ThinkPHP6.0启用软删除需三者协同:模型显式引入SoftDelete trait并设$useSoftDelete=true、数据库delete_time字段必须为NULL允许类型、操作必须走模型方法(如destroy()或delete()),缺一则退化为硬删。

在 ThinkPHP6.0 中启用软删除,核心是让数据“逻辑删除”而非物理删除——即写入一个时间戳字段(如 delete_time)标记已删,查询时自动过滤掉这些记录。它不是开箱即用的开关,而是需要模型、字段、调用方式三者协同生效。
模型必须显式启用 SoftDelete 并配置字段
在模型类中引入 trait 并声明关键属性:
- 添加
use think\model\concern\SoftDelete; - 声明
protected $deleteTime = 'delete_time';(字段名需与数据库一致) -
必须设置
protected $useSoftDelete = true;(尤其 TP6.0.0–6.0.7 版本,缺此行会退化为硬删) - 若字段名不是
delete_time(比如叫deleted_at),必须同步修改$deleteTime值
数据库字段类型必须支持 NULL
delete_time 字段不能设为 NOT NULL,也不能带 DEFAULT CURRENT_TIMESTAMP 或 ON UPDATE 约束。推荐定义为:
-
DATETIME NULL(最常用) - 或
BIGINT UNSIGNED NULL(用于时间戳整型存储) - 若字段被设为
NOT NULL DEFAULT '1970-01-01',软删写入NULL会被 MySQL 拒绝,restore()也静默失败
正确调用软删除与恢复操作
所有软删和恢复行为必须走模型层,避开 Db 类直操作:
- 软删除:用
UserModel::destroy(123)或UserModel::find(456)->delete()→ 写入delete_time,不删行 - 查软删数据:用
UserModel::onlyTrashed()->find(789)(只查已软删的) - 恢复数据:先查出实例,再调用
restore()方法:$user = UserModel::onlyTrashed()->find(101);<br>if ($user) { $user->restore(); } - 禁止写法:
UserModel::where('id', 101)->restore()(报错)、Db::table('user')->delete(101)(跳过软删逻辑,丢失事件与关联)
注意 restore() 静默失败的排查路径
返回 false 不代表报错,需按顺序检查:
- 数据库中该行
delete_time是否仍为非空?若是,说明写入失败,查 MySQL 错误日志或开启 SQL 日志定位 - 模型是否真启用了软删?
var_dump($user->getOptions())看soft_delete是否为true - 关联模型(如订单表)是否也启用了
SoftDelete?否则$user->orders()->onlyTrashed()查不到数据
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











