Laravel 5.8 验证 - 始终遵守任何规则

Posted

技术标签:

【中文标题】Laravel 5.8 验证 - 始终遵守任何规则【英文标题】:Laravel 5.8 Validation - always bail on any rule 【发布时间】:2019-08-08 12:27:22 【问题描述】:

是否有可能将FormRequest 规则设置为默认使用bail 规则而不输入它?

代替:

class StoreRequest extends FormRequest 
    function rules() 
        return [
            'name' => 'bail|required|min:3',
            'last_name' => 'bail|required|min:3',
            'names' => 'bail|required|min:3',
            'email' => 'bail|required|email',
            'type' => 'integer|min:10|max:50',
            // [...]
        ];
    

我想要更干净的版本,比如:

class StoreRequest extends FormRequest 

    protected $stopsOnFirstError = true; // I can't find anything like this

    function rules() 
        return [
            'name' => 'required|min:3',
            'last_name' => 'required|min:3',
            'names' => 'required|min:3',
            'email' => 'required|email',
            'type' => 'integer|min:10|max:50',
            // [...]
        ];
    

更新:

我的一些规则被定义为数组:

'type' => [
    'bail',
    'required',
    'integer',
    Rule::in(ContactType::getValues()),
],

【问题讨论】:

我认为这需要覆盖现有的验证器函数。 bail 已经隐含在 required 规则中,因此没有必要。但是bail 无法阻止其他字段验证它只会停止它正在验证的一个字段上的其他验证规则。 这就是我试图实现的目标 - 在第一次失败时停止其他验证。我也没有必填字段,但在存在时进行了验证:`bail|integer|min:10'。 【参考方案1】:

1) 在不使其更复杂的情况下使用字符串替换

<?php
$rules = [
            'name' => 'required|min:3',
            'last_name' => 'required|min:3',
            'names' => 'required|min:3',
            'email' => 'required|email'
        ];
$stopsOnFirstError = true;
if(stopsOnFirstError)
  array_walk($rules, function(&$value, $key)  $value = 'bail|'.$value;  );


print_r($rules);
?>

现场演示:Link

输出:

Array
(
    [name] => bail|required|min:3
    [last_name] => bail|required|min:3
    [names] => bail|required|min:3
    [email] => bail|required|email
)

2)你也可以通过其他方式做到这一点,只需添加'*' =&gt; 'bail',即可申请所有字段

class StoreRequest extends FormRequest 
    function rules() 
        return [
            '*' => 'bail',
            'name' => 'required|min:3',
            'last_name' => 'required|min:3',
            'names' => 'required|min:3',
            'email' => 'required|email',
        ];
    

【讨论】:

非常有趣的方法 好主意,但我有一些规则定义为带有闭包的数组或Rule::in 方法。我更新了我的问题。 @Daniel:所以不适用于'*' =&gt; 'bail',?你试过了吗? @NikleshRaut:我刚刚检查过,不幸的是它不起作用。 相当简单的方法。这个想法似乎很有趣。如果 Laravel 默认有这样的选项就好了【参考方案2】:

您始终可以在表单请求类中覆盖validator 方法:

class StoreRequest extends FormRequest 

    private function prependBailOnRule($rule) 
        if (is_string($rule)) 
            return "bail|".$rule;
         else if (is_array($rule)) 
           return array_merge([ "bail" ], $rule);
        
    

    //Adapted from FromRequest::createDefaultValidator
    public function validator(ValidationFactory $factory) 
        return $factory->make(
             $this->validationData(), 
             array_map([$this, 'prependBailOnRule' ], $this->container->call([$this, 'rules'])),
             $this->messages(), $this->attributes()
        );
    

    function rules() 
        return [
            'name' => 'required|min:3',
            'last_name' => 'required|min:3',
            'names' => 'required|min:3',
            'email' => 'required|email',
            'type' => 'integer|min:10|max:50',
            // [...]
        ];
    

【讨论】:

【参考方案3】:

这里我使用的是 Laravel 8,并通过设置 $stopOnFirstFailure = true 轻松停止对第一个错误的验证;

class StoreRequest extends FormRequest
protected $stopOnFirstFailure = true;

public function rules()

    return [
        'name'      => 'required|min:3',
        'last_name' => 'required|min:3',
        'names'     => 'required|min:3',
        'email'     => 'required|email',
    ];

【讨论】:

以上是关于Laravel 5.8 验证 - 始终遵守任何规则的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JWT API - Laravel 5.8 上验证用户群?

Laravel 5.8 验证在使用 Passport 失败后返回首页

Laravel 5.8访问错误messageBag进行数组验证

laravel 5.8 中的嵌套替代验证 required_without

Laravel 5.8:验证多个输入

如何在 laravel 5.8 或 6 中制作通用自定义包进行身份验证。*