在Laravel 5中使用After Validation Hook有什么用?

时间:2015-11-17 20:02:41

标签: php validation laravel-5 laravel-5.1

我正在学习Laravel 5并尝试验证数据库中是否存在电子邮件,然后在失败时添加一些自定义消息。我在Laravel的文档中找到了After Validation Hook

//as above

if (emailExist($email)) {
    $validator->errors()->add('email', 'This email has been used!');
}

//redirect as above

但我真的不明白这是什么。因为我可以这样做:

By locatorBase = By.xpath("./div/div[contains(@class,'listRoot')]";
By relativeLocator = getNthZElementLocator("2");
ByChanged chainedLocator = new ByChained(locatorBase, relativeLocator);

它仍然输出相同的结果。我什么时候应该使用第一个来验证某些东西而不是第二个?

3 个答案:

答案 0 :(得分:5)

第一种方法的目的只是保持包含在Validator对象中的所有内容,使其更具可重用性。

是的,在你的情况下它完全相同。但想象一下,如果你想验证多个项目。

foreach ($inputs as $input) {
    $validator->setData($input);

    if ($validator->fails()) { ... }
}

在你的情况下,你将不得不添加"如果"检查循环。现在想象必须在许多不同的地方运行此验证(多个控制器,可能是控制台脚本)。现在你在3个不同的文件中有这个if语句,下次你去修改它你的工作量是你工作量的3倍,也许你忘记在一个地方改变它......

我无法想到许多用例,但这是它背后的基本理念。

顺便提一下,有一个名为exists的验证规则可能会处理您的emailExist()方法

$rules = [
    'email' => 'exists:users,email',
];

http://laravel.com/docs/5.1/validation#rule-exists

答案 1 :(得分:0)

在许多情况下,您可能会觉得有必要。

仅假设您正在尝试为项目构建REST api。并且您已经决定,更新请求方法将不对请求中的任何字段进行任何必需的规则验证(因为可能有很多参数,并且您不想仅将其更改为一列就传递它们,或者您可能没有所有列,因为您将无法访问它)。

那么您将如何在UpdatePostRequest.php类中处理此验证,在该类中,您已按照代码中的说明将所有验证规则放入rules()方法中。

还可能要求两个或更多请求字段的值之和应大于或小于某个阈值数量。那怎么了?

我同意,您可以只在控制器中检查它并从那里重定向它,但是如果我们要在控制器中进行这些检查,它不会破坏创建专用请求类的目的。

我觉得控制器应该整洁,并且不应基于验证有多个退出点。这些小的验证检查可以通过创建新规则或扩展您自己的自定义验证或在验证钩子之后创建来在请求类中进行处理,它们在Laravel中都有其独特的用法。

因此,您可能想要在此处创建一个验证钩子,在该钩子中分配该钩子,如下面的示例所示,检查请求是否为空

public function withValidator($validator)
    {
        $validator->after(function ($validator) {
            if (empty($this->toArray())) {
                $validator->errors()->add('body', 'Request body cannot be empty');
            }
             if (!$this->validateCaptcha()) {
                $validator->errors()->add('g-recaptcha-response', 'invalid');
            }


        });
    }

这是完整的示例。

<?php

namespace App\Http\Requests\Posts;


use App\Helpers\General\Tables;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class UpdatePostRequest extends FormRequest
{
    public function authorize()
    {
        return auth()->user()->can('update-post', $this);
    }

    public function rules()
    {
        return [
            'name' => ['string', 'min:3', 'max:255'],

            'email' => ['string', 'email', 'min:3', 'max:255'],
            'post_data' => ['string', 'min:3',  'max:255'],
        ];
    }

    public function withValidator($validator)
    {
        $validator->after(function ($validator) {
            if (empty($this->toArray())) {
                $validator->errors()->add('body', 'Request body cannot be empty');
            }
        });
    }


}

谢谢..

答案 2 :(得分:0)

passedValidation 方法将在 FormRequest 类中通过验证时触发。实际上这个方法是对 afterValidation 方法的重命名。 See: method rename Commit

所以你可以喜欢

class RegistrationRequest extends FormRequest
{

     /**
     * Handle a passed validation attempt.
     *
     * @return void
     */
    protected function passedValidation()
    {
        $this->merge(
            [
                'password'  => bcrypt($this->password),
            ]
        );
    }
}