Laravel 软删除通过标记 deleted_at 字段实现数据逻辑删除,需添加字段、引入 SoftDeletes trait 并设置 $dates 属性,delete() 方法自动填充 deleted_at,查询默认忽略已删除数据,withTrashed() 包含已删记录,onlyTrashed() 仅查已删数据,restore() 恢复,forceDelete() 永久删除,支持 restoring、restored 等事件监听,适用于需保留历史的数据场景。
在 Laravel 中,软删除(Soft Deleting)是一种让数据“看似”被删除,实则保留在数据库中的机制。它通过标记一条记录为已删除,而不是真正从数据库中移除,从而保留数据完整性,便于后续恢复或审计。Laravel 的 Eloquent ORM 提供了非常简洁的方式来实现软删除功能。
要在模型中启用软删除,需完成以下三个步骤:
1. 修改数据库迁移文件
在创建表或修改表结构时,使用 softDeletes() 方法添加 deleted_at 字段:
Schema::table('users', function (Blueprint $table) {
$table->softDeletes();
});
这会创建一个可为空的 deleted_at 时间戳字段。
2. 在模型中使用 SoftDeletes Trait
打开对应的 Eloquent 模型(如 User.php),引入 SoftDeletes:
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
}
加入 $dates 后,deleted_at 会被自动转换为 PHP 的 Carbon 实例,方便日期操作。
启用后,调用模型的 delete() 方法不会真正删除记录,而是填充 deleted_at 字段为当前时间。
被软删除的记录示例:
$user = User::find(1); $user->delete(); // 软删除 // 查询包含已删除用户 User::withTrashed()->find(1); // 恢复用户 $user->restore(); // 永久删除 $user->forceDelete();
Laravel 默认会在所有查询中自动添加 WHERE deleted_at IS NULL 条件,这就是为什么普通 find() 或 get() 看不到已删除数据的原因。
你可以根据需要切换查询范围:
软删除和恢复操作会触发相应的 Eloquent 事件:
你可以在模型中监听这些事件,执行额外逻辑:
protected static function booted()
{
static::restored(function ($user) {
// 用户被恢复时执行
Log::info('User restored: ' . $user->id);
});
}
基本上就这些。只要记得加字段、用 Trait、理解查询作用域,软删除用起来非常自然。日常开发中适合用于用户、文章、订单等需要保留历史记录的场景。