能恢复,但必须先查到软删记录且模型字段配对;直接restore()会静默失败。需用withtrashed()查所有数据、onlytrashed()查已删数据,restore()须在带deleted_at的实例上调用,批量恢复注意事件、关联与事务。

能恢复,但必须先查到软删记录,且模型和字段都得配对;直接 restore() 调用会静默失败或报错。
查不到软删数据?默认查询自动过滤
软删除后数据还在表里,但 User::find(1)、User::where(...)->get() 全部跳过 deleted_at IS NOT NULL 的行。这不是 bug,是 Eloquent 默认行为。
- 要查“所有数据(含已软删)”,必须加
withTrashed():User::withTrashed()->find(1) - 只查“已被软删的”,用
onlyTrashed():User::onlyTrashed()->where('email', 'x@y.z')->first() - 如果
onlyTrashed()->find(1)返回null,说明这条记录没被软删过——可能根本没执行过delete(),或者已被forceDelete()物理删掉
restore() 是实例方法,不是静态调用
User::restore() 会报 Call to undefined method restore();restore() 必须在已加载的模型实例上调用,且该实例得带 deleted_at 值。
PHP中文网提供Laravel 13.2.0版本下载,Laravel框架 是基于 PHP 8.3+ 的高性能框架,官方推荐通过 Composer 安装。它内置 AI SDK、JSON:API Resources 及原生向量搜索,支持属性驱动开发与队列路由,大幅提升开发效率。相比旧版,13.2.0 优化了缓存 TTL 管理与实时通信,无需 Redis 即可横向扩展。作为现代 Web 开发首选,它兼顾安全与极速体验,助您快速构建企业级应用。
- ✅ 正确:
$user = User::withTrashed()->find(123); $user->restore(); - ❌ 错误:
User::find(123)->restore()(find()拿不到软删行,$user是null) - ❌ 错误:
User::onlyTrashed()->where(...)->restore()(这是静态调用,虽 Laravel 允许,但不触发restoring/restored事件) - 恢复失败时默认返回
false,无异常;可用restoreOrFail()强制抛异常便于捕获
批量恢复要注意事件、关联和事务
批量调用 restore() 看似方便,但绕过模型生命周期,容易漏掉关键逻辑。
- 用
Model::onlyTrashed()->where(...)->restore()是 SQL UPDATE,不触发restoring/restored事件,也不走访问器/修改器 - 关联模型(如
Post的Comment)不会自动恢复,得手动查Comment::withTrashed()->where('post_id', $post->id)->restore() - 涉及日志、统计、权限变更等联动操作时,必须包在
DB::transaction()里,否则部分成功会导致状态不一致 - 大批量(比如 >500 条)建议用
chunkById()分片 + 每批独立事务,防超时和内存溢出
恢复失败的常见硬坑
表面调了 restore() 却没生效,往往卡在这些地方:
-
deleted_at字段类型不对:必须是TIMESTAMP NULL或DATETIME NULL,设成NOT NULL DEFAULT CURRENT_TIMESTAMP会导致 UPDATE 失败 - 模型没真正启用
SoftDeletes:检查是否漏写use SoftDeletes;,或$casts里把'deleted_at' => 'date'这类错误覆盖了类型解析 - 事务未提交:在
DB::transaction()里调了restore(),但后续代码抛异常或忘记return,导致回滚 - 自定义主键匹配失败:模型设了
protected $primaryKey = 'uuid';,但你还用find(123)查数字 ID,自然找不到
最常被忽略的是:软删除恢复不是“更新数据”,而是“状态回切”。它不走 saving/saved,只走 restoring/restored —— 如果你在 saving 里写了唯一性校验或自动填充,它根本不会运行。










