【问题标题】:Custom placeholders for custom validation rules in Laravel 5Laravel 5 中自定义验证规则的自定义占位符
【发布时间】:2015-06-02 05:44:06
【问题描述】:

我在我的 Laravel 应用程序中创建了一组自定义验证规则。我首先在App\Http 目录中创建了一个validators.php 文件:

/**
 * Require a certain number of parameters to be present.
 *
 * @param  int     $count
 * @param  array   $parameters
 * @param  string  $rule
 * @return void
 * @throws \InvalidArgumentException
 */

    function requireParameterCount($count, $parameters, $rule) {

        if (count($parameters) < $count):
            throw new InvalidArgumentException("Validation rule $rule requires at least $count parameters.");
        endif;

    }


/**
 * Validate the width of an image is less than the maximum value.
 *
 * @param  string  $attribute
 * @param  mixed   $value
 * @param  array   $parameters
 * @return bool
 */

    $validator->extend('image_width_max', function ($attribute, $value, $parameters) {

        requireParameterCount(1, $parameters, 'image_width_max');

        list($width, $height) = getimagesize($value);

        if ($width >= $parameters[0]):
            return false;
        endif;

        return true;

    });

然后我将在我的AppServiceProvider.php 文件中添加包含此内容(同时还在此文件顶部添加use Illuminate\Validation\Factory;):

public function boot(Factory $validator) {

    require_once app_path('Http/validators.php');

}

然后在我的表单请求文件中,我可以调用自定义验证规则,如下所示:

$rules = [
    'image' => 'required|image|image_width:50,800',
];

然后在位于 resources/lang/en 目录下的 Laravel validation.php 文件中,我向数组中添加另一个键/值,以在验证返回 false 且失败时显示错误消息,如下所示:

'image_width' => 'The :attribute width must be between :min and :max pixels.',

一切正常,它会正确检查图像,如果失败则显示错误消息,但我不确定如何将:min:max 替换为表单请求文件中声明的值(50,800),同样的方式:attribute 被替换为表单字段名称。所以目前它显示:

The image width must be between :min and :max pixels.

而我希望它像这样显示

The image width must be between 50 and 800 pixels.

我在 Validator.php 主文件 (vendor/laravel/framework/src/Illumiate/Validation/) 中看到了一些 replace* 函数,但我似乎不太明白如何让它与我自己的自定义验证规则一起工作。

【问题讨论】:

    标签: php laravel laravel-5 laravel-validation


    【解决方案1】:

    我在 Laravel 5.4 中使用这样的东西:

    AppServiceProvider.php

    public function boot()
    {
        \Validator::extend('contains_field', 'App\Validators\ContainsFieldValidator@validate');
        \Validator::replacer('contains_field', 'App\Validators\ContainsFieldValidator@replace');
    }
    

    App\Validators\ContainsFieldValidator.php

    class ContainsFieldValidator
    {
        public function validate($attribute, $value, $parameters, Validator $validator)
        {
            $required = $parameters[0];
            $requiredDefault = isset($parameters[1]) ?: null;
    
            if (!$required && !$requiredDefault) {
                return false;
            }
    
            $requiredValue = isset($validator->attributes()[$required]) ? $validator->attributes()[$required] : $requiredDefault;
    
            return !(strpos($value, $requiredValue) === false);
        }
    
        public function replace($message, $attribute, $rule, $parameters)
        {
            return str_replace([':required'], str_replace('_', ' ', $parameters[0]), $message);
        }
    }
    

    【讨论】:

      【解决方案2】:

      这是我使用的解决方案:

      在 composer.json 中:

      "autoload": {
          "classmap": [
              "app/Validators"
          ],
      

      在 App/Providers/AppServiceProvider.php 中:

      public function boot()
      {
          $this->app->validator->resolver(
              function ($translator, $data, $rules, $messages) {
                  return new CustomValidator($translator, $data, $rules, $messages);
              });
      }
      

      在 App/Validators/CustomValidator.php 中

      namespace App\Validators;
      
      use Illuminate\Support\Facades\DB;
      use Illuminate\Validation\Validator as Validator;
      
      class CustomValidator extends Validator
      {
          // This is my custom validator to check unique with
          public function validateUniqueWith($attribute, $value, $parameters)
          {
              $this->requireParameterCount(4, $parameters, 'unique_with');
              $parameters    = array_map('trim', $parameters);
              $parameters[1] = strtolower($parameters[1] == '' ? $attribute : $parameters[1]);
              list($table, $column, $withColumn, $withValue) = $parameters;
      
              return DB::table($table)->where($column, '=', $value)->where($withColumn, '=', $withValue)->count() == 0;
          }
      
          // All you have to do is create this function changing
          // 'validate' to 'replace' in the function name
          protected function replaceUniqueWith($message, $attribute, $rule, $parameters)
          {
              return str_replace([':name'], $parameters[4], $message);
          }
      }
      

      :name 在此 replaceUniqueWith 函数中被 $parameters[4] 替换

      在 App/resources/lang/en/validation.php 中

      <?php
      return [
          'unique_with' => 'The :attribute has already been taken in the :name.',
      ];
      

      在我的控制器中,我这样称呼这个验证器:

      $organizationId = session('organization')['id'];    
      $this->validate($request, [
          'product_short_title' => "uniqueWith:products,short_title,
                                    organization_id,$organizationId,
                                    Organization",
      ]);
      

      这就是我的表单中的样子:)

      【讨论】:

        【解决方案3】:

        我没有用过这种方式,但你可能可以使用:

        $validator->replacer('image_width_max',
            function ($message, $attribute, $rule, $parameters) {
                return str_replace([':min', ':max'], [$parameters[0], $parameters[1]], $message);
            });
        

        【讨论】:

        • 我很快就会对此进行测试,并让您知道我的进展情况,谢谢!
        • 工作愉快,我很感激。
        猜你喜欢
        • 2015-01-26
        • 2017-04-11
        • 2018-02-18
        • 2019-02-12
        • 2016-11-22
        • 2015-09-07
        • 2015-06-14
        • 2016-01-13
        • 2016-10-21
        相关资源
        最近更新 更多