使用正则表达式在 Laravel 验证中传递自定义参数

D. *_*rov 3 php validation laravel error-messaging laravel-5.6

好的,我在这里遇到了一个非常困难的情况,我想我要么错过了一些已经存在的重要东西,要么 Laravel 没有提供一种方法来实现这一点。我想用我想在消息中替换的自定义占位符指定自定义验证错误消息。问题在于:我正在使用Laravel 文档明确指出的regex验证规则,应该更好地将其传递给数组以避免不必要的分隔符行为。情况如下:我想指定一个用于验证的全局多语言消息,我已经这样做了:name.regex

'custom' => [
    'name' => [
        'regex' => 'The :attribute must corespond to the given format: :format!'
    ]
]
Run Code Online (Sandbox Code Playgroud)

如您所见,我:format在该消息中放置了一个自定义占位符,因为对于name不同类的属性,我将匹配不同的正则表达式。所以我希望能够在验证过程中输入每个给定正则表达式的自定义人类可读描述(作为参数)。所以我在我的控制器中执行以下操作:

$input = Input::all();
$validator = Validator::make($input, [
        'name' => ['required', 'regex:/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u']
    ]);
Run Code Online (Sandbox Code Playgroud)

我还有一个Validator::replacer()方法AppServiceProvider.php可以替换:format消息中的占位符:

Validator::replacer('regex', function($message, $attr, $rule, $parameters){
        return str_replace(':format', "I would like to be able to somehow retrieve the custom format description here, but using \$parameters[] is not an option", $message);
    });
Run Code Online (Sandbox Code Playgroud)

regex验证规则的问题是我真的不允许在验证器中向它传递参数,例如:

$validator = Validator::make($input, [
        'name' => ['required', 'regex:/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u,Thats my custom validator format description']
    ]);
Run Code Online (Sandbox Code Playgroud)

因为它完全弄乱了正则表达式(应该是这样)。所以我不能在 my 中使用 $parameters 1 $replacer()来替换占位符。此外,将整个句子作为验证规则的逗号分隔参数传递真的很不方便。所以这个概念不符合需求。

:format值将是动态的,并且会因不同类的name字段要求而严重变化,所以我真的需要将动态多语言描述设置为当前验证器实例的属性。我想也许最方便的场景是这样的:

$validator = Validator::make($input, [
        'name' => ['required', 'regex:/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u', 'format:Current name requirements described here.']
    ]);
Run Code Online (Sandbox Code Playgroud)

并且 Laravel 以某种方式知道:format应该由该实例消息中某处的当前规则替换。我想过把这个额外的参数显式添加为验证规则,然后再管理它,但我真的无法实现跨规则连接(换句话说,获取新format规则的参数并在regex规则中使用它)。我真的不知道如何解决这个问题,任何帮助将不胜感激。提前致谢!

PS我知道我每次都可以通过这种方式指定整个消息:

$input = Input::all();
$validator = Validator::make($input, [
        'name' => ['required', 'regex:/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u']
    ],
[
    'name.regex' => 'My custom message here'
]);
Run Code Online (Sandbox Code Playgroud)

但我不想每次都输入整个消息,因为它以后可能包含其他占位符(可能是全局的),我想使用通过validator.php文件提供的多语言基本消息,所以我真的需要更换:format唯一的。

Chi*_*ung 5

您可以创建自定义规则:

php artisan make:rule CustomRegex
Run Code Online (Sandbox Code Playgroud)

然后更新构造函数以支持格式的正则表达式和描述。

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class CustomRegex implements Rule
{
    /** @var string $attribute The attribute of we are validating. */
    public $attribute;

    /** @var string $description The description of the regex format. */
    public $description;

    /** @var string $regex The regex to validate. */
    public $regex;

    /**
     * Create a new rule instance.
     *
     * @param string $regex The regex to validate.
     * @param string $description The description of the regex format.
     * @return void
     */
    public function __construct(string $regex, string $description)
    {
        $this->regex = $regex;
        $this->description = $description;
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $this->attribute = $attribute;

        return preg_match($this->regex, $value);
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return trans('validation.custom.name', [
            'attribute' => $this->attribute,
            'format' => $this->description
        ]);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后当你验证时:

use App\Rules\CustomRegex;

request()->validate([
    'name' => [
        'required', new CustomRegex('/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u', 'The description of your format')
    ]
]);
Run Code Online (Sandbox Code Playgroud)

然后输出消息将如下所示:

名称必须对应于给定的格式:您的格式的描述!