【问题标题】:Pass custom parameters in Laravel Validation with regex使用正则表达式在 Laravel 验证中传递自定义参数
【发布时间】:2018-11-04 15:42:51
【问题描述】:

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

'custom' => [
    'name' => [
        'regex' => 'The :attribute must corespond to the given format: :format!'
    ]
]

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

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

我的AppServiceProvider.php 中还有一个Validator::replacer() 方法,它应该替换消息中的: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);
    });

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

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

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

:format 值将是动态的,并且在不同类的name 字段要求中会有很大差异,因此我确实需要将动态多语言描述设置为当前验证器实例的属性。我想也许最方便的情况是这样的:

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

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

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

$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'
]);

但我不想每次都输入整个消息,因为它稍后可能包含其他占位符(可能是全局的左右),我想使用通过 @ 提供的多语言基本消息987654343@ 文件,所以我真的只需要替换:format

【问题讨论】:

    标签: php laravel validation laravel-5.6 error-messaging


    【解决方案1】:

    您可以创建自定义规则:

    php artisan make:rule CustomRegex
    

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

    <?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
            ]);
        }
    }
    

    然后当你验证时:

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

    那么输出消息将如下所示:

    名称必须与给定格式相对应:格式的描述!

    【讨论】:

    • 我今天醒来后想了一会儿,现在我看到你提到了完全相同的事情!谢谢!如果在下一个版本中开箱即用,我会很高兴。我的意思是,只是更详细一点的regex 规则版本,这样你也可以传递参数。没那么必要,但会很有帮助。
    【解决方案2】:

    在 Laravel 5.6 中我能想到的最简单的方法是使用闭包:

    $validator = Validator::make($input, 
        [
            'name' => 
               [
                 'required',
                 function($attribute, $value, $fail) {
    
                     $regex = '/^\p{Lu}\p{L}+ \p{Lu}\p{L}+$/u';
    
                     if (!preg_match($regex, $value)) {
    
                        return $fail('Your custom message with' .
                        $attribute . ' name and its value = ' . $value);
                     }
                 },
               ]
        ]);
    

    在这个闭包中,你可以添加任何你想要的东西。您可以计算可读格式的表格并将其添加到错误消息中。

    【讨论】:

    • 查看我的最后一个 P.S.这种功能(设置当前的 [b]whole[/b] 错误消息)已经可以通过Validator::make() 函数的第三个参数 ($messages) 获得。问题是我真的不想每次都重写整个消息,而是能够输入我自己的单个参数 [b] 并且 [/b] 仍然使用 @987654324 中指定的消息库@翻译文件。
    猜你喜欢
    • 2013-12-17
    • 2018-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-04
    • 2019-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多