【问题标题】:Laravel custom messages for array validation用于数组验证的 Laravel 自定义消息
【发布时间】:2016-10-21 21:22:07
【问题描述】:

我有一个表单,并且我有一个用于视频 url 的输入字段数组,现在当我验证表单时,如果我有多个带有视频 url 的无效字段,我会为每个无效字段收到相同的消息,因为我做了我自己的自定义消息。我不希望每个输入字段都有相同的错误消息,并且我不希望字段名称与错误消息一起显示的数组的默认 Laravel 错误消息,而不是那样,我希望有错误消息带有值,在这种情况下是用户编写的 url。该怎么做?

这是我的请求文件,其中包含消息和规则:

public function messages(){

    $messages = [
      'title.required' => 'Du må ha tittel.',
      'type.required' => 'Du må velge artikkeltype.',
      'category.required' => 'Du må velge kategori.',
      'summary.required' => 'Du må ha inngress.',
      'text.required' => 'Du må ha artikkeltekst.',
      'active_url' => 'Du må ha gyldig url.',
    ];
  }

  public function rules(){

    $rules = [
      'external_media.*' => 'active_url',
      'title' => 'required',
      'type' => 'required',
      'category' => 'required',
      'summary' => 'required',
      'text' => 'required',
      //'image' => 'required|image|max:20000',
    ];

    return $rules;

  }

更新了代码,让问题更清晰

当我有这样的请求文件时:

public function messages(){

    $messages = [
      'title.required'    => 'Du må ha tittel.',
      'type.required'    => 'Du må velge artikkeltype.',
      'category.required'    => 'Du må velge kategori.',
      'summary.required'    => 'Du må ha inngress.',
      'text.required'    => 'Du må ha artikkeltekst.',
      'external_media.active_url' => 'Du må ha gyldig url.',
   ];

   return $messages;
  }

  public function rules(){

    $rules = [
      'external_media.*' => 'active_url',
      'title' => 'required',
      'type' => 'required',
      'category' => 'required',
      'summary' => 'required',
      'text' => 'required',
      //'image' => 'required|image|max:20000',
    ];

    return $rules;

  }

我得到了输出:

The external_media.0 is not a valid URL.
The external_media.1 is not a valid URL.
The external_media.2 is not a valid URL.

我想取每个输入的值,而不是那种输出,并有类似的东西:

The htt:/asdfas.com  is not a valid URL.

【问题讨论】:

    标签: php laravel


    【解决方案1】:
    public function messages() {
    
        $messages = [
            'title.required'    => 'Du må ha tittel.',
            'type.required'     => 'Du må velge artikkeltype.',
            'category.required' => 'Du må velge kategori.',
            'summary.required'  => 'Du må ha inngress.',
            'text.required'     => 'Du må ha artikkeltekst.',
    
        ];
    
        foreach ($this->get('external_media') as $key => $val) {
            $messages["external_media.$key.active_url"] = "$val is not a valid active url";
        }
    
        return $messages;
    
    }
    

    【讨论】:

    【解决方案2】:

    要使用验证语言文件之外的自定义消息,您可以这样使用:

    $messages = ['username.required' => 'customeError'];
    
    $validator = \Validator::make(
        $data,
        ['username' => 'required'],
        messages
    );
    

    您可以将自定义消息的数组作为第三个参数传递,就像我在上面使用的那样。希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      对于 laravel 7.x,我找到了以下解决方案。基本可以用'field.rule' => 'message'

      public function rules() 
      {
         return [
            'user.*.firstname' => 'string|required',
         ];
      }
      

      然后在消息中(我对所有请求都使用 FormRequest):

      public function messages() 
      {
         'user.*.firstname.required' => 'Firstname of the user is required',
      }
      

      您还可以将'passwords.user' 之类的翻译字符串传递给消息。

      【讨论】:

        【解决方案4】:

        如果您在视图页面中使用“name=location[]”,我认为这会对您有所帮助。

         for ($i = 0; $i <= sizeof($location); $i++) {
         $this->validate($request,
         [
        // set the rules
          'location.'.$i => 'required',
          'contact_no.'.$i => 'required',
           'email.'.$i => 'required|email',
         ], 
        [
        // set your custom error messages here 
          'location.'.$i.'.'.'required' => 'Contact no. is required', 
          'contact_no.'.$i.'.'.'required' => 'Contact no. is required',
          'email.'.$i.'.'.'required' => 'Email is required',
          'email.'.$i.'.'.'email' => 'Please enter valid email address'
        ]);
        }
        

        【讨论】:

          【解决方案5】:
          public function messages()
                  {
                      $messages = [];
                      foreach ($this->request->get('external_media') as $key => $val) {
                          $messages['external_media.' . $key . '.active_url'] = 'The '.$val .' is not a valid URL.'
                      }
                      return $messages;
                  }
          

          【讨论】:

            【解决方案6】:

            这在 laravel 5.5 中对我来说很好

            $request->validate([
                        'files.*' => 'required|mimes:jpeg,png,jpg,gif,pdf,doc|max:10000'
                    ],
                    [
                        'files.*.mimes' => 'Los archivos solo pueden estar con formato: jpeg, png, jpg, gif, pdf, doc.',
                    ]
                );
            

            【讨论】:

              【解决方案7】:
              'external_media.*.required' => 'active_url',
              

              【讨论】:

                【解决方案8】:

                使用潜在解决方案进行编辑

                经过一番挖掘,我查看了 Validator 类以及它如何添加错误消息以查看它是否有任何可用的占位符。

                Illuminate\Validation\Validator 中,我认为运行以验证请求的函数是validate,它依次运行每个规则并添加错误消息。与添加错误信息相关的一段代码就是这个,在函数的最后:

                    $value = $this->getValue($attribute);
                
                    $validatable = $this->isValidatable($rule, $attribute, $value);
                
                    $method = "validate{$rule}";
                
                    if ($validatable && ! $this->$method($attribute, $value, $parameters, $this)) {
                        $this->addFailure($attribute, $rule, $parameters);
                    }
                

                如您所见,它实际上并没有传递在添加失败时通过验证的字段的值,这反过来又添加了错误消息。

                我已经设法让一些工作来实现您所追求的目标。如果您将这两个方法添加到您的基本 Request 类中,该类通常位于 App\Http\Requests\Request

                protected function formatErrors(Validator $validator)
                {
                    $errors = parent::formatErrors($validator);
                
                    foreach ($errors as $attribute => $eachError) {
                        foreach ($eachError as $key => $error) {
                            if (strpos($error, ':value') !== false) {
                                $errors[$attribute][$key] = str_replace(':value', $this->getValueByAttribute($attribute), $error);
                            }
                        }
                    }
                
                    return $errors;
                }
                
                protected function getValueByAttribute($attribute)
                {
                    if (($dotPosition = strpos($attribute, '.')) !== false) {
                        $name = substr($attribute, 0, $dotPosition);
                        $index = substr($attribute, $dotPosition + 1);
                
                        return $this->get($name)[$index];
                    }
                
                    return $this->get($attribute);
                }
                

                然后在您的验证消息中,您应该能够放置 :value 替换器,它应该替换为已验证的实际值,如下所示:

                public function messages()
                {
                    return [
                        'external_media.*.active_url' => 'The URL :value is not valid'
                    ];
                }
                

                我注意到您的代码存在一些问题:

                • 在您的messages 函数中,您为active_url 提供了一条消息,它是规则的名称,而不是字段的名称。这应该是external_media
                • 您没有从messages 函数返回$messages 变量。您需要在末尾添加return $messages;

                然而,关于您的问题,您编写此代码的类是Illuminate\Http\Request 的一个实例,您应该能够在生成错误消息时访问提供给该请求的实际值。例如,您可以这样做:

                public function messages()
                {
                    return [
                        'external_media' => 'The following URL is invalid: ' . $this->get('external_media')
                    ];
                }
                
                public function rules()
                {
                    return [
                        'external_media' => 'active_url'
                    ];
                }
                

                这将包括错误消息中提供给external_media 的值。希望这会有所帮助。

                【讨论】:

                • 当我按照您的建议进行操作时,出现错误:数组到字符串的转换
                • 哦,对了,我想我现在明白了。我不认为这是可能的 - 我会更新我的答案
                • 你在正确的轨道上。检查我对工作解决方案的评论
                【解决方案9】:

                您可以使用Customizing The Error Format

                protected function formatErrors(Validator $validator)
                {
                    $results = [];
                    $flag = false;
                    $messages = $validator->errors()->messages();
                    foreach ($messages as $key => $value) {
                        if (!str_contains($key, 'external_media') || !$flag) {
                            $results[] = $value[0];
                        }
                        if (str_contains($key, 'external_media') && !$flag) {
                            $flag = true;
                        }
                    }
                    return $results;
                }
                

                【讨论】:

                • 看起来这在 5.5 中被删除了:/
                【解决方案10】:

                你可以作为

                $messages = [
                    'title.required' => 'Du må ha tittel.',
                    'type.required' => 'Du må velge artikkeltype.',
                    'category.required' => 'Du må velge kategori.',
                    'summary.required' => 'Du må ha inngress.',
                    'text.required' => 'Du må ha artikkeltekst.',
                    'active_url' => 'Du må ha gyldig url.',
                ];
                
                $validator = Validator::make($data, [
                    'external_media.*' => 'active_url',
                    'title' => 'required',
                    'type' => 'required',
                    'category' => 'required',
                    'summary' => 'required',
                    'text' => 'required',
                    //'image' => 'required|image|max:20000'
                ], $messages);
                
                if ($validator->fails()){
                    // handle validation error
                } else {
                    // no validation error found
                }
                

                【讨论】:

                  猜你喜欢
                  • 2017-11-19
                  • 2014-05-31
                  • 2017-06-28
                  • 2017-12-13
                  • 2016-01-29
                  • 2020-07-18
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-07-13
                  相关资源
                  最近更新 更多