本文目录导读:

在Laravel中处理验证后的回调,有多种方式可以实现,以下是几种常用的方法和实践:
使用 FormRequest 类(推荐)
创建 FormRequest
php artisan make:request StoreUserRequest
定义验证规则和回调
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Validation\ValidationException;
class StoreUserRequest extends FormRequest
{
/**
* 确定用户是否有权执行此请求
*/
public function authorize(): bool
{
return true;
}
/**
* 获取应用于请求的验证规则
*/
public function rules(): array
{
return [
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|min:8',
];
}
/**
* 验证通过后的处理
*/
public function passedValidation()
{
// 验证通过后执行的代码
// 记录日志、修改数据等
\Log::info('用户验证通过', ['email' => $this->email]);
// 可以修改请求数据
$this->merge([
'password' => bcrypt($this->password),
'status' => 'active'
]);
}
/**
* 验证失败后的处理
*/
protected function failedValidation(Validator $validator)
{
// 自定义验证失败处理
// 记录日志
\Log::warning('用户验证失败', [
'errors' => $validator->errors()->toArray()
]);
throw (new ValidationException($validator))
->errorBag($this->errorBag)
->redirectTo($this->getRedirectUrl());
}
}
在控制器中手动验证回调
使用 Validator facade
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Contracts\Validation\Validator as ValidatorContract;
class UserController extends Controller
{
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|min:8',
]);
// 验证通过后回调
$validator->after(function ($validator) {
// 验证通过后额外检查
// 检查域名
$email = $validator->getData()['email'] ?? '';
if (strpos($email, 'spam.com') !== false) {
$validator->errors()->add('email', '不允许使用该邮箱域名');
}
});
if ($validator->fails()) {
// 验证失败处理
return redirect()->back()
->withErrors($validator)
->withInput();
}
// 验证通过后的处理
$this->onValidationSuccess($request, $validator);
// 继续处理业务逻辑
return redirect()->route('users.index');
}
private function onValidationSuccess(Request $request, ValidatorContract $validator)
{
// 验证通过后的业务处理
\Log::info('验证通过', $validator->validated());
// 可以获取验证后的数据
$validated = $validator->validated();
// 修改数据
$validated['password'] = bcrypt($validated['password']);
// ... 其他业务逻辑
}
}
使用 validated() 方法
public function store(Request $request)
{
// 手动验证
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|min:8',
]);
// 验证通过后,这里可以获取经过验证的数据
$validatedData = $request->validated();
// 验证后的回调处理
$this->afterValidation($validatedData);
// 创建用户
$user = User::create($validatedData);
return response()->json($user, 201);
}
private function afterValidation(array $data)
{
// 验证通过后的处理逻辑
\Log::info('处理验证后的数据', $data);
// 可以添加额外逻辑
event(new UserValidated($data));
}
使用事件监听
创建验证事件
<?php
namespace App\Events;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class UserValidated
{
use Dispatchable, SerializesModels;
public $data;
public function __construct(array $data)
{
$this->data = $data;
}
}
监听事件
<?php
namespace App\Listeners;
use App\Events\UserValidated;
use Illuminate\Support\Facades\Log;
class HandleUserValidation
{
public function __construct()
{
//
}
public function handle(UserValidated $event)
{
// 处理验证通过后的逻辑
Log::info('用户验证通过', $event->data);
// 发送通知、记录日志等
$this->sendWelcomeEmail($event->data['email']);
}
private function sendWelcomeEmail($email)
{
// 发送邮件逻辑
}
}
中间件方式实现
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class CustomValidation
{
public function handle(Request $request, Closure $next)
{
if ($this->shouldSkipValidation($request)) {
return $next($request);
}
$validator = Validator::make($request->all(), $this->rules($request));
// 验证通过后的回调
$validator->after(function ($validator) use ($request) {
// 在这里添加额外的验证后逻辑
});
if ($validator->fails()) {
return response()->json([
'errors' => $validator->errors()
], 422);
}
// 将验证通过的数据合并到请求
$request->merge($validator->validated());
return $next($request);
}
private function rules(Request $request): array
{
return [
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
];
}
private function shouldSkipValidation(Request $request): bool
{
// 根据条件决定是否跳过验证
return false;
}
}
完整的实际使用示例
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreUserRequest;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class UserController extends Controller
{
public function store(StoreUserRequest $request): JsonResponse
{
// 开启数据库事务
try {
DB::beginTransaction();
// 验证已经通过,FormRequest 的 passedValidation 已经执行
$validatedData = $request->validated();
// 额外处理
$this->processAfterValidation($validatedData);
// 创建用户
$user = User::create($validatedData);
// 事务提交
DB::commit();
// 记录日志
Log::info('用户创建成功', ['user_id' => $user->id]);
return response()->json([
'success' => true,
'message' => '用户创建成功',
'data' => $user
], 201);
} catch (\Exception $e) {
DB::rollBack();
Log::error('用户创建失败', [
'error' => $e->getMessage(),
'request_data' => $request->all()
]);
return response()->json([
'success' => false,
'message' => '用户创建失败'
], 500);
}
}
private function processAfterValidation(array $data): void
{
// 验证通过后的处理逻辑
// 同步数据到第三方服务
$this->syncToThirdParty($data);
// 或者创建一个关联记录
$this->createProfile($data);
}
private function syncToThirdParty(array $data): void
{
// 同步数据到第三方服务
}
private function createProfile(array $data): void
{
// 创建用户配置文件
}
}
最佳实践建议
- 使用 FormRequest:对于复杂验证,使用 FormRequest 是最佳实践
- 遵循单一职责:验证逻辑和业务逻辑要分离
- 日志记录:验证前后的关键步骤都要记录日志
- 错误处理:提供清晰的错误信息给用户
- 性能优化:合理地使用缓存和队列
- 代码复用:将通用的验证逻辑抽离成 trait 或服务类
选择合适的回调方式取决于你的具体需求和项目架构,FormRequest 是最常用的方式,因为它提供了清晰的验证流程和回调机制。