Laravel 自定义验证顺序

Laravel Custom Validation Order

我添加自定义验证规则

Validator::extend('validate_timezone', function($attribute, $value, $parameters, $validator) {
    $items = request('items');
    $from_date = Carbon::createFromFormat('Y-m-d H:i:s', $item['from_date']);
    // my code below depend on $from_date
    ......
    ......

    return true;
);

验证规则

 "from_date" => "required|date_format:Y-m-d H:i:s|validate_timezone",

问题,在'date_format:Y-m-d H:i:s'之前自定义验证validate_timezone 运行,所以如果日期格式错误,我会在validate_timezone函数[=18]中出错=]

如何在自定义验证 validate_timezone 之前强制验证 date_format:Y-m-d H:i:s

documentation中可以找到以下内容:

Rules will be validated in the order they are assigned.

表示代码按预期工作。 您可能正在寻找 bail 选项:

Sometimes you may wish to stop running validation rules on an attribute after the first validation failure. To do so, assign the bail rule to the attribute

这意味着你应该试试这个:

"from_date" => "bail|required|date_format:Y-m-d H:i:s|validate_timezone",

自定义扩展验证规则首先是运行,因为它可能定义在服务提供者的启动函数中,它在每次请求时运行,因此您需要捕获 Carbon 异常和 return false因此

public function boot()
{
    \Validator::extend('validate_timezone', function ($attribute, $value, $parameters, $validator) {
        try {
            $from_date = Carbon::createFromFormat('Y-m-d H:i:s', $value);
            return true;
        } catch (Exception $ex) {
            logger()->warning($ex->getMessage());
            return false;
        }
    });
}

现在如果 carbon 无法从传递的格式创建,它会抛出一个我们捕获、记录并 return false

的异常

正如@PtrTon提到的,您需要在第一次验证失败时退出

现在假设这样的验证逻辑

Route::post('/', function () {
    $validate = request()->validate([
        "from_date" => "bail|required|date_format:Y-m-d H:i:s|validate_timezone",
    ]);
    dd($validate);
});

还有这样的视图表单

<form action="/" method="post">
    @csrf
    <input type="datetime" name="from_date" value="2019-10-16 15:03">
    <button type="submit">Submit</button>
</form>
@if ($errors->any())
<div class="alert alert-danger">
    <ul>
        @foreach ($errors->all() as $error)
        <li>{{ $error }}</li>
        @endforeach
    </ul>
</div>
@endif

date_from 的值对 date_formatvalidate_timezone 都无效,但只有 date_format 的验证错误消息将被 returned

希望这对您有所帮助