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

gsk*_*gsk 37 php custom-validators laravel laravel-5 laravel-validation

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

  protected $rules = [
      'shipping_country' => ['max:60'],
      'items' => ['array|numericarray']
];
Run Code Online (Sandbox Code Playgroud)

我的cusotom功能如下

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

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

luk*_*ter 41

Validator::extend()像你一样使用实际上非常好,你只需要将它放在这样的服务提供者中:

<?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()
    {
        //
    }
}
Run Code Online (Sandbox Code Playgroud)

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

'providers' => [
    // Other Service Providers

    'App\Providers\ValidatorServiceProvider',
],
Run Code Online (Sandbox Code Playgroud)

您现在可以在numericarray任何地方使用验证规则


Adr*_*wan 40

虽然上述答案是正确的,但在很多情况下,您可能只想为某个表单请求创建自定义验证.您可以利用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',
        ];
    }
}
Run Code Online (Sandbox Code Playgroud)


pro*_*mer 20

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

将验证器方法添加到父请求将扩展的请求中:

<?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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您的所有特定请求都将如下所示:

<?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!'
        ];
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这实际上是在5.3.23中命名为`withValidator`:https://github.com/laravel/framework/commit/bf8a36ac3df03a2c889cbc9aa535e5cf9ff48777 (4认同)

vgu*_*ero 9

替代Adrian Gunawan 的解决方案,现在也可以这样处理:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreBlogPost extends FormRequest
{
    public function rules()
    {
        return [
            'title' => ['required', 'not_lorem_ipsum'],
        ];
    }

    public function withValidator($validator)
    {
        $validator->addExtension('not_lorem_ipsum', function ($attribute, $value, $parameters, $validator) {
            return $value != 'lorem ipsum';
        });

        $validator->addReplacer('not_lorem_ipsum', function ($message, $attribute, $rule, $parameters, $validator) {
            return __("The :attribute can't be lorem ipsum.", compact('attribute'));
        });
    }
}

Run Code Online (Sandbox Code Playgroud)


gk.*_*gk. 8

自定义规则对象

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

php artisan make:rule NumericArray
Run Code Online (Sandbox Code Playgroud)

在 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...';
  }
}
Run Code Online (Sandbox Code Playgroud)

然后在表单请求中有

use App\Rules\NumericArray;
.
.
protected $rules = [
      'shipping_country' => ['max:60'],
      'items' => ['array', new NumericArray]
];
Run Code Online (Sandbox Code Playgroud)

  • 当我将它与 JS 验证(https://github.com/proengsoft/laravel-jsvalidation)一起使用时,出现错误:trim() 期望参数 1 为字符串,给定的对象。我通过在 NumericArray 类中添加一个“公共函数 __toString(){return 'NumericArray ';}”来解决它。https://github.com/mpociot/laravel-apidoc-generator/issues/247 (3认同)

Mar*_*łek 5

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

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 这个答案比创建整个服务提供商更好,特别是当您只需要使用一次规则时. (2认同)