PHP项目Laravel验证后回调处理

wen PHP项目 3

本文目录导读:

PHP项目Laravel验证后回调处理

  1. 使用 FormRequest 类(推荐)
  2. 在控制器中手动验证回调
  3. 使用事件监听
  4. 中间件方式实现
  5. 完整的实际使用示例
  6. 最佳实践建议

在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
    {
        // 创建用户配置文件
    }
}

最佳实践建议

  1. 使用 FormRequest:对于复杂验证,使用 FormRequest 是最佳实践
  2. 遵循单一职责:验证逻辑和业务逻辑要分离
  3. 日志记录:验证前后的关键步骤都要记录日志
  4. 错误处理:提供清晰的错误信息给用户
  5. 性能优化:合理地使用缓存和队列
  6. 代码复用:将通用的验证逻辑抽离成 trait 或服务类

选择合适的回调方式取决于你的具体需求和项目架构,FormRequest 是最常用的方式,因为它提供了清晰的验证流程和回调机制。

抱歉,评论功能暂时关闭!