本文目录导读:

在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 是最常用的方式,因为它提供了清晰的验证流程和回调机制。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播