在Laravel首次失败后,如何停止所有验证?

时间:2018-08-16 07:25:42

标签: laravel

Laravel中有一个名为bail的函数,该函数会在失败时停止验证。如果我想在第一次失败时停止所有验证怎么办?

例如:

$request->validate([
    'antibotprotection' => 'bail|required|exists:protectioncodes,protection_code|max:255',
    'email' => 'required|string|email|max:255|unique:users',
]);

此代码将停止对antibotprotection的验证,但随后将继续验证电子邮件,并传递错误以查看有关电子邮件的内容,这使整个目的无法实现。第一次失败后,我该如何停止整个validate功能?

2 个答案:

答案 0 :(得分:1)

./app/Validation/BailingValidator.php

<?php

namespace App\Validation;

use Illuminate\Support\MessageBag;
use Illuminate\Validation\Validator;

class BailingValidator extends Validator
{
    /**
     * Determine if the data passes the validation rules.
     *
     * @return bool
     */
    public function passes()
    {
        $this->messages = new MessageBag;

        // We'll spin through each rule, validating the attributes attached to that
        // rule. Any error messages will be added to the containers with each of
        // the other error messages, returning true if we don't have messages.
        foreach ($this->rules as $attribute => $rules) {
            $attribute = str_replace('\.', '->', $attribute);

            foreach ($rules as $rule) {
                $this->validateAttribute($attribute, $rule);

                if ($this->shouldStopValidating($attribute)) {
                    break 2;
                }
            }
        }

        // Here we will spin through all of the "after" hooks on this validator and
        // fire them off. This gives the callbacks a chance to perform all kinds
        // of other validation that needs to get wrapped up in this operation.
        foreach ($this->after as $after) {
            call_user_func($after);
        }

        return $this->messages->isEmpty();
    }
}

./app/Providers/AppServiceProvider.php

...
use App\Validation\BailingValidator;
use Illuminate\Contracts\Translation\Translator;
use Illuminate\Contracts\Validation\Factory;
use Illuminate\Support\ServiceProvider;
...
    public function boot()
    {
        /**
         * @var \Illuminate\Validation\Factory $factory
         */
        $factory = resolve(Factory::class);

        $factory->resolver(function (Translator $translator, array $data, array $rules, array $messages, array $customAttributes) {
            return new BailingValidator($translator, $data, $rules, $messages, $customAttributes);
        });
    }
...

./app/Http/Controller/SomeController.php

...
        $this->validate($request, [
            'foo' => ['bail', 'required'],
            'bar' => ['bail', 'required'],
        ]);
...

{"message":"The given data was invalid.","errors":{"foo":["The foo field is required."]}}

答案 1 :(得分:1)

为解决此问题,我使用array_unique$errors数组中删除了重复的错误代码,我知道它只能解决显示部分,但对我而言,我只关心它。这是一个示例:

@if ($errors->any())
    <div class="alert alert-danger">
        @foreach (array_unique($errors->all()) as $error)
            <div>{!! ucfirst($error) !!}</div>
        @endforeach
    </div>
@endif