软删除通过添加deleted_at字段并使用softdeletes trait实现,支持逻辑删除、查询软删记录、恢复及强制物理删除。

如果您的PHP应用需要在不真正删除数据库记录的情况下实现逻辑删除功能,则软删除是一种常见且安全的解决方案。以下是实现软删除与数据恢复的具体步骤:
一、添加软删除字段到数据表
软删除依赖于数据库中一个标记字段,用于标识记录是否已被“删除”。该字段通常为布尔型或时间戳类型,便于查询过滤和状态判断。
1、使用迁移工具(如Laravel Migrate)执行以下SQL语句添加字段:
ALTER TABLE users ADD deleted_at TIMESTAMP NULL;
2、确保该字段允许为空值,以便未删除记录的deleted_at值为NULL。
立即学习“PHP免费学习笔记(深入)”;
3、为deleted_at字段创建索引以提升查询性能:
CREATE INDEX idx_users_deleted_at ON users(deleted_at);
二、在模型中启用软删除功能
通过在Eloquent模型中引入SoftDeletes Trait,可自动拦截delete()调用并更新deleted_at字段,同时使常规查询默认排除已软删除记录。
1、在模型类顶部引入命名空间:
use Illuminate\Database\Eloquent\SoftDeletes;
2、在类定义中声明使用Trait:
class User extends Model { use SoftDeletes; }
3、确认模型中的$dates属性包含deleted_at:
protected $dates = ['deleted_at'];
三、执行软删除操作
调用delete()方法时,Eloquent将不再执行DELETE SQL语句,而是将当前时间写入deleted_at字段,使该记录在后续普通查询中不可见。
1、获取目标模型实例:
$user = User::find(123);
2、调用delete()触发软删除:
$user->delete();
3、验证deleted_at字段已被赋值:
此时数据库中deleted_at字段值为当前时间戳,而非NULL。
四、查询包含已软删除记录
默认情况下,Eloquent会自动在WHERE子句中添加deleted_at IS NULL条件。若需检索全部记录(含已软删除),必须显式调用withTrashed()方法。
1、查询所有记录(包括软删除):
$users = User::withTrashed()->get();
2、仅查询已软删除的记录:
$deletedUsers = User::onlyTrashed()->get();
3、在链式查询中组合使用:
User::withTrashed()->where('name', 'like', '%admin%')->get();
五、恢复已软删除的数据
恢复操作即清空deleted_at字段,使记录重新出现在常规查询结果中。此过程不涉及INSERT或UPDATE其他字段,仅重置软删除标记。
1、获取已软删除的模型实例:
$user = User::withTrashed()->find(123);
2、调用restore()方法清除deleted_at值:
$user->restore();
3、确认deleted_at字段已设为NULL:
执行后数据库中deleted_at字段值恢复为NULL。
六、强制执行物理删除
当确认某条记录永久失效且无需保留历史时,可绕过软删除机制直接从数据库中移除该行。此操作不可逆,需谨慎使用。
1、获取已软删除的模型实例:
$user = User::withTrashed()->find(123);
2、调用forceDelete()执行真实删除:
$user->forceDelete();
3、验证记录已从数据库中彻底消失:
该ID对应的数据行不再存在于users表中。










