laravel的软删除通过Softdeletes trait实现,模型引入该trait并添加deleted_at字段即可标记删除而不移除记录,便于数据恢复与完整性维护。

Laravel 的软删除(Soft Deletes)是一种优雅的方式,用来标记数据为“已删除”,而不会真正从数据库中移除记录。这样可以在需要时恢复数据,同时保持数据完整性。Laravel 通过 SoftDeletes trait 提供了开箱即用的支持,使用起来非常简单。
启用软删除功能
要在模型中启用软删除,只需在对应的 Eloquent 模型中引入 IlluminatedatabaseEloquentSoftDeletes trait,并确保数据表包含一个 deleted_at 字段。
示例:启用软删除的 User 模型
<?php namespace AppModels; use IlluminateDatabaseEloquentModel; use IlluminateDatabaseEloquentSoftDeletes; class User extends Model { use SoftDeletes; protected $dates = ['deleted_at']; // 可选:如果使用 $dates,可直接操作 Carbon 实例 }
注意: Laravel 6+ 中,$dates 属性不再是必须的,Eloquent 会自动识别 deleted_at 为日期类型。
数据库迁移中添加 deleted_at 字段
要支持软删除,数据表必须包含一个 Nullable 的 deleted_at 字段。可以使用迁移文件中的 softDeletes() 方法来添加它。
示例:创建用户表并添加软删除字段
<?php use IlluminateDatabaseMigrationsMigration; use IlluminateDatabaseSchemaBlueprint; use IlluminateSupportFacadesSchema; class CreateUserstable extends Migration { public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('deleted_at')->nullable(); // 手动写法 // 或者使用下面这行: // $table->softDeletes(); $table->timestamps(); }); } public function down() { Schema::dropIfExists('users'); } }
提示: 使用 $table->softDeletes(); 是更简洁的方式,它会自动生成一个 nullable 的 timestamp 类型的 deleted_at 字段。
执行软删除与恢复
一旦模型启用了软删除,调用 delete() 方法不会真正删除记录,而是将 deleted_at 设置为当前时间。
示例:执行软删除
$user = User::find(1); $user->delete(); // 此时 deleted_at 被设置,数据仍在数据库中
要恢复已被软删除的记录,可以调用 restore() 方法。
示例:恢复已删除的记录
$user = User::withTrashed()->find(1); $user->restore(); // 恢复数据,deleted_at 设为 null
说明:
- delete():设置 deleted_at 时间戳
- restore():清除 deleted_at,恢复数据
- forceDelete():彻底删除记录,绕过软删除
查询软删除数据
默认情况下,启用了软删除的模型查询会自动排除已被删除的记录。但你可以使用以下方法控制查询行为:
- withTrashed():包含已被软删除的记录
- onlyTrashed():只查询已被软删除的记录
- withoutTrashed():排除软删除数据(默认行为)
示例:不同查询方式
// 获取所有用户,包括已删除的 $users = User::withTrashed()->get(); // 只获取已删除的用户 $trashedUsers = User::onlyTrashed()->get(); // 恢复某个已删除用户 User::onlyTrashed()->where('email', 'test@example.com')->restore();
强制删除(永久删除)
如果你确定要永久删除某条记录,可以使用 forceDelete() 方法。
$user = User::find(1); $user->forceDelete(); // 数据从数据库中彻底删除
对已经软删除的数据再次调用 forceDelete() 也会将其永久移除。
软删除事件
Laravel 的软删除会触发特定的模型事件:
- deleting 和 deleted:在 delete() 调用时触发(软删除也触发)
- restoring 和 restored:在 restore() 调用时触发
你可以在模型中监听这些事件,用于清理关联数据或记录日志。
protected static function booted() { static::deleted(function ($user) { // 删除用户时,清理其文章草稿 $user->drafts()->delete(); }); static::restored(function ($user) { // 恢复用户时,重新激活其账号状态 $user->update(['status' => 'active']); }); }
基本上就这些。软删除在实际项目中非常实用,比如用户注销、内容回收站等场景。只要记得加字段、用 trait、理解查询作用域,就能轻松掌握。