Laravel表单请求数组验证自定义规则

时间:2017-07-03 13:28:38

标签: forms laravel validation

我想创建一个表单请求验证,并且不知道如何操作。

我有一张表格:

<form>
  <input type="text" name="fullname[0]">
  <input type="text" name="document_num[0]">

  <input type="text" name="fullname[1]">
  <input type="text" name="document_num[1]">

  <input type="text" name="fullname[2]">
  <input type="text" name="document_num[2]">

   .....

  <input type="text" name="fullname[n]">
  <input type="text" name="document_num[n]">

  <input type="submit">
</form>

表&#39;用户&#39;:

  id | fullname | document_num
  1  | John     | 111
  2  | Jane     | 112
 ..  | ...      | ...

当用户点击提交时,请求被发送到控制器方法,其中它首先由表单请求进行验证(或者它可以是常规验证器)。 所以我想编写一条规则来检查:

for (i=0; i<numberOfUsersToAdd; i++)

    if  (‘document_num[$i]’ exists in ‘users’ in field ‘document_num’ ) {

       $user = Users::find(id of user in DB having this ‘document_num[$i]’) ; 

       check if (fullname[$i] == $user->fullname) {

                return true} // input-ed users name match his/her name in DB.

        else {return false}  // input-ed users name doesn't match his/her name in DB.

        } 

    else return true; // document_num[$i] doesn't exists in the database which's ok

如果是单词:检查表用户中是否存在任何输入的document_num [$ i],如果是,则从DB获取具有此document_nubmer的用户,并将他/她的fullname值与输入的fullname [$ i]进行比较

怎么做?:)

感谢任何帮助!:)

1 个答案:

答案 0 :(得分:2)

确定。 YourFormRequest中此验证的逻辑是下一个:

  1. 让我们根据需要标记所有字段,并将document_num字段另外标记为整数。您可以添加其他附加约束 - 这没关系。
  2. rules YourFormRequest方法检查循环&#34;用户是否存在给定document_num?&#34;。
  3. 如果不存在则ok - 验证此字段是否成功。
  4. 如果存在,则检查&#34;是给定fullname的用户全名等于。如果等于那么好 - 这个领域的验证是成功的。否则,如果失败,则将始终失败的自定义规则附加到此字段。
  5. 让我们在一个工作示例中看到这种方法。

    YourFormRequest.php

    public function rules()
    {
        $rules = [
            'fullname.*' => 'required',
            'document_num.*' => 'required|integer',
        ];
    
        $documentNums = request()->get('document_num');
        $fullnames = request()->get('fullname');
    
        for ($i = 0; $i < count($documentNums); $i++) {
            $user = User::where('document_num', $documentNums[$i])->first();
            if ($user && ($user->fullname != $fullnames[$i]) {
                $rules['document_num.' . $i] = "document_num_fail:$i"; //some rule that always fails. As argument we pass a row number of field that fails
            }
        }
        return $rules;
    }
    

    CustomValidator.php(例如将它放在App \ Services文件夹中)

    namespace App\Services;
    
    class CustomValidator {
    
        public function documentNumFailValidate($attribute, $value, $parameters, $validator) {
            return false;
        }
    
        public function documentNumFailReplacer($message, $attribute, $rule, $parameters) {
            return str_replace([':index'], $parameters[0], $message);
        }
    }
    

    在这里你可以看到两个功能。首先 - 验证规则(我们总是传递错误的原因,我们需要它)。第二 - 它只是错误消息的替代品。您想知道此错误在哪个字段行上(例如,分别在第三行和字段:fullname [2]和document_num [2])。正如我在评论附加失败规则时所写的那样,我们给出了验证方法失败的行数(documentNumFailReplacer方法将替换占位符:错误消息中的索引与给定值)

    下一步 - 在AppServiceProvider.php中注册此方法

    public function boot()
    {
        Validator::extend('document_num_fail',  'App\Services\CustomValidator@documentNumFailValidate');
        Validator::replacer('document_num_fail', 'App\Services\CustomValidator@documentNumFailReplacer');
    }
    

    最后一步 - 在validation.php中定义自定义消息

    'custom' => [
            'document_num.*' => [
                'document_num_fail' => 'Input-ed user name doesn`t match his/her name in DB for specified :attribute (field position/number: :index)',
            ]
        ],
    
    'attributes' => [
        'document_num.*' => 'document number',
    ],