本文目录导读:

在 PHP 项目中,请求验证层的放置位置取决于你的项目架构,以下是常见的几种方案:
控制器内验证(小型项目)
class UserController extends Controller
{
public function store(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|min:8'
]);
// 处理业务逻辑
}
}
FormRequest 类(Laravel 推荐)
// app/Http/Requests/StoreUserRequest.php
class StoreUserRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|min:8'
];
}
}
// 控制器中使用
class UserController extends Controller
{
public function store(StoreUserRequest $request)
{
$validated = $request->validated();
// 业务逻辑
}
}
Service 层验证(大型项目/DDD)
// app/Services/UserService.php
class UserService
{
private UserValidator $validator;
public function __construct(UserValidator $validator)
{
$this->validator = $validator;
}
public function create(array $data)
{
$validatedData = $this->validator->validate($data);
// 业务逻辑
}
}
// app/Validators/UserValidator.php
class UserValidator
{
public function validate(array $data): array
{
$validator = Validator::make($data, [
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users'
]);
if ($validator->fails()) {
throw new ValidationException($validator);
}
return $validator->validated();
}
}
中间件验证(特定场景)
// app/Http/Middleware/ValidateApiKey.php
class ValidateApiKey
{
public function handle($request, Closure $next)
{
if (!$request->has('api_key')) {
return response()->json(['error' => 'Missing API key'], 400);
}
return $next($request);
}
}
// 路由中使用
Route::middleware(['validate.api.key'])->group(function () {
Route::post('/data', [DataController::class, 'store']);
});
独立验证层(复杂业务)
app/
├── Http/
│ ├── Controllers/
│ └── Requests/ # FormRequest 放这里
├── Services/
│ └── UserService.php # 业务逻辑
├── Validators/
│ ├── UserValidator.php
│ └── OrderValidator.php
├── Models/
└── Rules/ # 自定义验证规则
├── UniqueTogether.php
└── PhoneNumber.php
推荐方案对比
小型项目 (Laravel)
- 使用 FormRequest(方案2)
- 简单直观,自动处理错误响应
中型项目
- FormRequest + Service 层
- 验证逻辑集中在 Request 类,业务逻辑在 Service
大型项目/微服务
- 独立 Validator 类(方案3)
- 解耦清晰,便于单元测试
- 支持复杂验证逻辑复用
API 服务
- 结合中间件(方案4)处理认证/API Key
- 使用 FormRequest 处理数据验证
- 统一错误响应格式
最佳实践建议
- 保持验证集中:避免验证逻辑分散在各处
- 错误信息统一:使用统一的错误响应格式
- 验证优先级:先格式验证,再业务验证,最后权限验证
// 组合使用示例
class UserController extends Controller
{
public function store(StoreUserRequest $request)
{
// 1. 先通过 FormRequest 进行格式验证
$validated = $request->validated();
// 2. 再在 Service 层进行业务验证
$this->userService->create($validated);
return response()->json(['message' => '用户创建成功'], 201);
}
}
选择哪种方案主要看项目规模和团队协作需求,重点是保持验证逻辑的可维护性和一致性。