本文目录导读:

在PHP API中实现软删除,通常是在数据库层面标记记录为“已删除”,而不是物理删除数据,以下是完整的实现方案:
数据库设计
首先在表中添加软删除字段:
ALTER TABLE users ADD COLUMN deleted_at TIMESTAMP NULL DEFAULT NULL, ADD COLUMN deleted_by INT NULL DEFAULT NULL;
Eloquent ORM 实现(Laravel)
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
// 自定义删除字段(默认使用 deleted_at)
const DELETED_AT = 'deleted_at';
// 可选:添加删除者关联
public function deleter()
{
return $this->belongsTo(User::class, 'deleted_by');
}
}
API 控制器实现
<?php
namespace App\Http\Controllers\Api;
use App\Models\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
// 查询(自动排除软删除数据)
public function index()
{
// 默认只返回未删除的数据
$users = User::all();
// 如果要包含软删除数据
// $users = User::withTrashed()->get();
// 只查软删除数据
// $users = User::onlyTrashed()->get();
return response()->json($users);
}
// 软删除
public function destroy($id)
{
$user = User::findOrFail($id);
$user->deleted_by = auth()->id(); // 设置删除者
$user->save();
$user->delete(); // 软删除
return response()->json(['message' => '删除成功']);
}
// 恢复软删除
public function restore($id)
{
$user = User::withTrashed()->findOrFail($id);
$user->restore();
return response()->json(['message' => '恢复成功']);
}
// 永久删除
public function forceDelete($id)
{
$user = User::withTrashed()->findOrFail($id);
$user->forceDelete();
return response()->json(['message' => '永久删除成功']);
}
}
自定义软删除实现(不使用ORM)
<?php
class SoftDeleteTrait
{
protected $table;
public function delete($id)
{
$sql = "UPDATE {$this->table}
SET deleted_at = NOW(),
deleted_by = ?
WHERE id = ? AND deleted_at IS NULL";
return DB::update($sql, [auth()->id(), $id]);
}
public function restore($id)
{
$sql = "UPDATE {$this->table}
SET deleted_at = NULL,
deleted_by = NULL
WHERE id = ? AND deleted_at IS NOT NULL";
return DB::update($sql, [$id]);
}
// 查询时自动过滤
public function query($conditions = [])
{
$sql = "SELECT * FROM {$this->table}
WHERE deleted_at IS NULL";
if (!empty($conditions)) {
$sql .= " AND " . implode(' AND ', $conditions);
}
return DB::query($sql);
}
}
API 路由配置
// routes/api.php
Route::apiResource('users', 'UserController');
Route::post('users/{id}/restore', 'UserController@restore');
Route::delete('users/{id}/force', 'UserController@forceDelete');
请求示例
# 软删除 DELETE /api/users/1 # 恢复 POST /api/users/1/restore # 永久删除 DELETE /api/users/1/force # 查询所有(包含软删除) GET /api/users?withTrashed=true
注意事项
- 唯一索引冲突:软删除时如果有唯一索引,需要考虑是否允许重复
- 关联删除:处理关联表的软删除策略
- 查询效率:确保deleted_at字段有索引
- 数据清理:定期清理软删除的旧数据
高级用法:全局作用域
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class SoftDeletingScope implements Scope
{
public function apply(Builder $builder, Model $model)
{
$builder->whereNull($model->getQualifiedDeletedAtColumn());
}
}
这样配置后,你的PHP API就完整支持了软删除功能。