在Yii框架中恢复软删除数据需先确认软删除机制启用且字段可空,再通过onlyTrashed()获取记录,最后调用restore()、手动置null保存或执行SQL更新;批量恢复须按规模选择循环、batchUpdate或分页事务方案。

在Yii框架中恢复已被软删除的数据,必须先确认模型启用软删除机制、数据库字段存在且可空,再通过特定查询作用域定位记录并重置删除标记;直接调用delete()或update()不触发软删逻辑,会导致状态错乱。
确认软删除已启用且字段配置正确
打开模型文件(如User.php),检查是否声明了use yii\behaviors\SoftDeleteBehavior;并绑定到behaviors()方法。若使用的是自定义软删字段(比如is_deleted),必须确保该字段在数据库中为TINYINT(1) NULL或DATETIME NULL——【字段类型非NULLABLE会导致restore操作静默失败】。
执行SQL验证:SELECT `id`, `deleted_at` FROM `user` WHERE `id` = 123;,若返回结果中deleted_at为NULL,说明未被软删;若为时间戳,则进入下一步。
查出软删除记录的两种方式
方法一:用withTrashed()查全部数据(含已软删)
User::find()->withTrashed()->where(['id' => 123])->one(); —— 这一步能拿到实例,但不能直接调restore(),因为Yii的软删行为由Behavior控制,不是Eloquent式原生支持。
方法二:用onlyTrashed()精准定位已软删记录
$user = User::find()->onlyTrashed()->where(['id' => 123])->one();
这一步返回的模型实例已携带软删状态,是后续恢复操作的唯一合法入口。如果返回null,说明该ID从未被软删过,或已被物理删除。
执行恢复操作的三个可靠路径
第一步:调用Behavior提供的restore()实例方法
$user->restore();
这是最标准的做法,会触发restoring和restored事件,并自动清除deleted_at或对应软删字段值。
第二步:手动设字段为null后保存
$user->deleted_at = null;
$user->save();
适用于Behavior未正确注册或字段名不匹配的场景。注意:必须显式赋null,写''或0无效。
第三步:用createCommand()直写SQL(绕过模型层)
Yii::$app->db->createCommand()
→ update('user', ['deleted_at' => null], 'id = :id', [':id' => 123])
→ execute();
速度快,无事件,适合后台批量清理。但【必须同步刷新应用缓存与关联模型状态】,否则前端仍可能读到旧态。
批量恢复软删数据的实操方案
① 小批量(≤50条):循环调用restore()
$ids = [101, 102, 105];
foreach ($ids as $id) {
$user = User::find()->onlyTrashed()->where(['id' => $id])->one();
if ($user) $user->restore();
}
② 中批量(50~500条):用createCommand()->batchUpdate()
Yii::$app->db->createCommand()
→ update('user', ['deleted_at' => null], ['in', 'id', $ids])
→ execute();
这一步比逐条快得多,且避免PHP内存溢出。记得事后清掉AR查询缓存:Yii::$app->cache->delete('user_list');
③ 大批量(>500条):分页+事务包裹
for ($offset = 0; $offset $chunk = array_slice($allIds, $offset, 100);
$transaction = Yii::$app->db->beginTransaction();
try {
Yii::$app->db->createCommand()
→ update('user', ['deleted_at' => null], ['in', 'id', $chunk])
→ execute();
$transaction->commit();
} catch (Exception $e) {
$transaction->rollBack();
throw $e;
}
}



















