首页 文章

在Laravel 5中使用表单请求验证时如何添加自定义验证规则

提问于
浏览
32

我正在使用表单请求验证方法来验证laravel 5中的请求 . 我想用表单请求验证方法添加我自己的验证规则 . 我的请求类在下面给出 . 我想添加自定义验证numeric_array和字段项 .

protected $rules = [
      'shipping_country' => ['max:60'],
      'items' => ['array|numericarray']
];

我的cusotom功能如下

Validator::extend('numericarray', function($attribute, $value, $parameters) {
            foreach ($value as $v) {
                if (!is_int($v)) {
                    return false;
                }
            }
            return true;
        });

如何在laravel5中使用此验证方法进行表单请求验证?

8 回答

  • 19

    像你一样使用 Validator::extend() 实际上非常好,你只需将它放在_1675754中就像这样:

    <?php namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    
    class ValidatorServiceProvider extends ServiceProvider {
    
        public function boot()
        {
            $this->app['validator']->extend('numericarray', function ($attribute, $value, $parameters)
            {
                foreach ($value as $v) {
                    if (!is_int($v)) {
                        return false;
                    }
                }
                return true;
            });
        }
    
        public function register()
        {
            //
        }
    }
    

    然后通过将提供程序添加到 config/app.php 中的列表来注册该提供程序:

    'providers' => [
        // Other Service Providers
    
        'App\Providers\ValidatorServiceProvider',
    ],
    

    您现在可以在任何位置使用 numericarray 验证规则

  • 33

    虽然上述答案是正确的,但在很多情况下,您可能只想为某个表单请求创建自定义验证 . 您可以利用laravel FormRequest并使用依赖注入来扩展验证工厂 . 我认为这个解决方案比创建服务提供商简单得多 .

    这是如何做到的 .

    use Illuminate\Validation\Factory as ValidationFactory;
    
    class UpdateMyUserRequest extends FormRequest {
    
        public function __construct(ValidationFactory $validationFactory)
        {
    
            $validationFactory->extend(
                'foo',
                function ($attribute, $value, $parameters) {
                    return 'foo' === $value;
                },
                'Sorry, it failed foo validation!'
            );
    
        }
    
        public function rules()
        {
            return [
                'username' => 'foo',
            ];
        }
    }
    
  • 40

    接受的答案适用于全局验证规则,但很多时候您将验证某些特定于表单的条件 . 以下是我在这些情况下推荐的内容(这似乎是出于line 75 of FormRequest.php的Laravel源代码):

    Add a validator method to the parent Request your requests will extend:

    <?php namespace App\Http\Requests;
    
    use Illuminate\Foundation\Http\FormRequest;
    use Validator;
    
    abstract class Request extends FormRequest {
    
        public function validator(){
    
            $v = Validator::make($this->input(), $this->rules(), $this->messages(), $this->attributes());
    
            if(method_exists($this, 'moreValidation')){
                $this->moreValidation($v);
            }
    
            return $v;
        }
    }
    

    Now all your specific requests will look like this:

    <?php namespace App\Http\Requests;
    
    use App\Http\Requests\Request;
    
    class ShipRequest extends Request {
    
        public function rules()
        {
            return [
                'shipping_country' => 'max:60',
                'items' => 'array'
            ];
        }
    
        // Here we can do more with the validation instance...
        public function moreValidation($validator){
    
            // Use an "after validation hook" (see laravel docs)
            $validator->after(function($validator)
            {
                // Check to see if valid numeric array
                foreach ($this->input('items') as $item) {
                    if (!is_int($item)) {
                        $validator->errors()->add('items', 'Items should all be numeric');
                        break;
                    }
                }
            });
        }
    
        // Bonus: I also like to take care of any custom messages here
        public function messages(){
            return [
                'shipping_country.max' => 'Whoa! Easy there on shipping char. count!'
            ];
        }
    }
    
  • -1

    您需要覆盖 Request 类中的 getValidatorInstance 方法,例如这样:

    protected function getValidatorInstance()
    {
        $validator = parent::getValidatorInstance();
        $validator->addImplicitExtension('numericarray', function($attribute, $value, $parameters) {
            foreach ($value as $v) {
                if (!is_int($v)) {
                    return false;
                }
            }
            return true;
        });
    
        return $validator;
    }
    
  • 5

    您不需要扩展验证器来验证数组项,您可以使用"*"验证数组的每个项目,如Array Validation中所示

    protected $rules = [
          'shipping_country' => ['max:60'],
          'items' => ['array'],
          'items.*' => 'integer'
    ];
    
  • 1

    Custom Rule Object

    一种方法是使用Custom Rule Object,这样您就可以根据需要定义任意数量的规则,而无需在Providers和控制器/服务中进行更改以设置新规则 .

    php artisan make:rule NumericArray
    

    在NumericArray.php中

    namespace App\Rules;
    class NumericArray implements Rule
    {
       public function passes($attribute, $value)
       {
         foreach ($value as $v) {
           if (!is_int($v)) {
             return false;
           }
         }
         return true;
       }
    
    
      public function message()
      {
         return 'error message...';
      }
    }
    

    然后在Form请求中

    use App\Rules\NumericArray;
    .
    .
    protected $rules = [
          'shipping_country' => ['max:60'],
          'items' => ['array', new NumericArray]
    ];
    
  • 3

    对我来说,工作的解决方案给了我们lukasgeiter,但不同的是我们创建了一个类,我们的自定义验证,如此,对于laravel 5.2 . *下一个示例是为第二个日期的日期范围添加验证必须等于或大于第一个

    在app / Providers中创建ValidatorExtended.php

    <?php
    namespace App\Providers;
    use Illuminate\Validation\Validator as IlluminateValidator;
    
    class ValidatorExtended extends IlluminateValidator {
    
    private $_custom_messages = array(
     "after_or_equal" => ":attribute debe ser una fecha posterior o igual a 
     :date.",
    );
    
    public function __construct( $translator, $data, $rules, $messages = array(),      
    $customAttributes = array() ) {
      parent::__construct( $translator, $data, $rules, $messages, 
      $customAttributes );
      $this->_set_custom_stuff();
    }
    
    protected function _set_custom_stuff() {
       //setup our custom error messages
      $this->setCustomMessages( $this->_custom_messages );
    }
    
    /**
     * La fecha final debe ser mayor o igual a la fecha inicial
     *
     * after_or_equal
     */
    protected function validateAfterOrEqual( $attribute, $value, $parameters, 
    $validator) {
       return strtotime($validator->getData()[$parameters[0]]) <= 
      strtotime($value);
    }
    
    }   //end of class
    

    好 . 现在让我们创建服务提供者 . 在app / Providers中创建ValidationExtensionServiceProvider.php,我们编码

    <?php
    namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    use Validator;
    
    class ValidationExtensionServiceProvider extends ServiceProvider {
    
    public function register() {}
    
    public function boot() {
      $this->app->validator->resolver( function( $translator, $data, $rules, 
      $messages = array(), $customAttributes = array() ) {
        return new ValidatorExtended( $translator, $data, $rules, $messages, 
        $customAttributes );
    } );
    }
    
    }   //end of class
    

    现在我们告诉Laravel加载这个服务提供者,在config / app.php和最后添加到providers数组

    //Servicio para extender validaciones
    App\Providers\ValidationExtensionServiceProvider::class,
    

    现在我们可以在函数规则的请求中使用此验证

    public function rules()
    {
      return [
        'fDesde'     => 'date',
        'fHasta'     => 'date|after_or_equal:fDesde'
     ];
    }
    

    或者在Validator中:make

    $validator = Validator::make($request->all(), [
        'fDesde'     => 'date',
        'fHasta'     => 'date|after_or_equal:fDesde'
    ], $messages);
    

    您必须注意,进行验证的方法的名称具有前缀validate并且采用驼峰案例样式validateAfterOrEqual,但是当您使用验证规则时,每个大写字母都用下划线和小写字母的字母替换 .

    所有这些我从https://www.sitepoint.com/data-validation-laravel-right-way-custom-validators//这里详细解释 . 谢谢他们 .

  • 0

    本页面上的所有答案都可以解决您的问题,但是......但Laravel惯例的唯一正确方法是来自Ganesh Karki的解决方案

    如果您想通过Laravel约定创建验证,请遵循本教程 . 它很简单,也很好解释 . 这对我帮助很大 .

    Tutorial link

相关问题