在 Laravel 中验证值之前如何规范化它?

How can I normalize a value before I validate it in Laravel?

我有这样的规则:

'email' => 'required|email|unique',

但是假设我想将 johnsmith+something@example.org 视为等同于 johnsmith@example.org,例如。有没有办法在我验证输入值之前对其进行标准化?

我考虑过为此使用中间件,采用 TrimStrings 的风格,但我只想在非常有选择性的基础上更改非空值,因此中间件方法的范围太大一张网。

像下面这样使用 rule class

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class EmailValidation implements Rule
{
    public function passes($attribute, $value)
    {
         //Perform logic on $value
         return trim($value) === $value;
    }
}

希望对您有所帮助。

似乎没有办法在通过验证规则时修改请求属性的值。经过更多考虑,我认为这可能是最好的。这意味着所谓的 "validation rules" 违反了 SRP,而且副作用可能是错误的巨大来源。

我已经意识到这里真正的问题是想要围绕 unique 规则包装一些规范化逻辑。

据我所知,这只能使用 validation extension,因为这是验证方法接收 Validator 对象实例的唯一方法。使用该对象,您可以在使用 Validator 应用 unique 规则之前规范化该值:

<?php

namespace App\Validators;

use Illuminate\Support\Str;
use Illuminate\Validation\Validator;

class UniqueEmail
{
    public function validate($attribute, $value, $parameters, Validator $validator)
    {
        $value = $this->normalize($value);

        return $validator->validateUnique($attribute, $value, $parameters);
    }

    protected function normalize($value)
    {
        // ...

        return $value;
    }
}

AppServiceProviderboot 方法中注册扩展:

Validator::extend('unique_email', 'App\Validators\UniqueEmail@validate');