thinkphp软删除恢复失败主因是数据库字段与模型配置未对齐:delete_time字段须为datetime/timestamp、允许null、默认null;模型需同时引入softdelete trait、声明use softdelete、设置$deletetime;恢复必须调用实例的restore()方法,不可链式调用,批量恢复需事务逐条或直写sql。

ThinkPHP 软删除不是“删了就没了”,而是给数据打个标记、留条后路。但很多人一恢复就失败——不是框架不行,是漏掉了数据库和模型之间那几处关键对齐点。
数据库字段必须满足三个硬性条件
软删除依赖 delete_time 字段真实承载状态,它不是可有可无的装饰字段:
- 类型必须是 DATETIME 或 TIMESTAMP(不支持 INT/BIGINT 时间戳,除非显式声明
$type = ['delete_time' => 'integer']) - Null 列值必须为 YES(即允许为空),不能设为 NOT NULL
- Default 值必须为 NULL,不能是
CURRENT_TIMESTAMP、'1970-01-01'等固定值
检查命令:DESCRIBE user; 若不符合,用这条语句修复:ALTER TABLE `user` MODIFY COLUMN `delete_time` DATETIME NULL DEFAULT NULL;
模型配置要三者同时生效
只写 use SoftDelete; 不够,必须三项并存:
- 引入 trait:
use think\model\concern\SoftDelete; - 类内声明:
use SoftDelete; - 定义字段:
protected $deleteTime = 'delete_time';(字段名必须与数据库完全一致)
TP6.0.0–6.0.7 版本还需额外加:protected $useSoftDelete = true;
TP6.0.8+ 可省略,但建议保留,避免版本升级后行为漂移。
恢复操作必须走实例,不能链式调用
restore() 是模型实例方法,不是查询构造器方法:
- ✅ 正确:
$user = UserModel::onlyTrashed()->find(123); $user->restore(); - ❌ 错误:
UserModel::onlyTrashed()->where('id', 123)->restore();(报错或静默失败) - ❌ 错误:
UserModel::where('id', 123)->restore();(方法不存在)
务必判断返回值:if (false === $user->restore()) { /* 记录日志,排查配置 */ }
批量恢复不能靠 restore(),得换思路
restore() 天然不支持批量,强行链式调用无效。两种安全做法:
-
逐条恢复 + 事务包裹(推荐):
Db::transaction(function () {<br> $ids = UserModel::onlyTrashed()->where('status', 1)->column('id');<br> foreach ($ids as $id) {<br> $user = UserModel::onlyTrashed()->find($id);<br> $user?->restore();<br> }<br>}); -
直写 SQL 绕过模型(紧急救火):
Db::name('user')->where('id', 'in', $ids)->update(['delete_time' => null]);
注意:跳过事件、验证和类型转换,仅用于无回调依赖的场景。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











