Laravel 5x 自定义数据验证

Laravel本身内置了许多好用的数据校验规则,拿来即用,但这远远不够,我们需要自定义自己的验证规则是必要的,先看一个简单的示例:

简单验证

直接在 app\Providers\AppServiceProvider.php 里扩展 Validator

打开 app\Providers\AppServiceProvider.php ,在 boot()方法里添加我们自己的验证规则,比方说我们需要一个验证是祖国的手机号码(+86):

namespace App\Providers;
 
use Illuminate\Support\ServiceProvider;
use Validator;
 
class AppServiceProvider extends ServiceProvider
{
 
    public function boot()
    {
        Validator::extend('cn_phone', function($attribute, $value, $parameters) {
            return substr($value, 0, 3) == '+86';
        });
    }
 
}

参考文档我们发现,自定义验证器闭包接收四个参数,分别是要验证的属性名称、属性值、传递给规则的参数数组以及 Validator 实例。

这里:cn_phone 是我们将在验证请求类中使用的规则名称,验证通过返回 TRUE , 失败返回 FALSE,参数 $attribute 是要验证的字段的名称,参数 $parameters 用于更复杂的验证规则,像 Laravel 中默认存在的 min:xsame:field 这种。

下面演示:
定义一个 /form_store 路由指向 FormControllerpostForm 方法,再定义个请求类 CreateUserRequest 依赖注入。

public function postForm(CreateUserRequest $request)
{
    return "Success!";
}

app\Http\Requests\CreateUserRequest.php

 'required|cn_phone',
        ];
    }
}

我就用自带的 welcome.blade.php 模板页面给大家演示一下:

@if(count($errors) > 0) @foreach($errors->all() as $error)
  • {{ $error }}
  • @endforeach @endif
    {{ csrf_field() }}

    preview:

    Laravel 5x 自定义数据验证_第1张图片
    image

    好像出错提示出来了,有木有,但是这不是我们想要的,我们要自定义一个错误消息。打开 resources/lang/en/validation.php 找到

    'custom' => [
            'attribute-name' => [
                'rule-name' => 'custom-message',
            ],
        ],
    

    按照此格式要求,改写成我们定义的验证字段和对应的返回错误消息提示:

    'custom' => [
            'phone' => [
                'zn_phone' => '请加手机号的国际区号+86',
            ],
        ],
    
    

    再次验证:


    Laravel 5x 自定义数据验证_第2张图片
    image

    这还远远不够,对于复杂的数据验证呢?

    复杂验证

    自定义的 Validator
    假设有这么个验证要求,是 phoneemail 当输入手机号时,邮箱就不能同时输入(什么奇葩需求),来看如何定义自己的验证类:

    首先我们想到的是这个自定义验证类放哪里好呢?这里我个人建议在 app 下新建一个目录,我取名为 Librarys ,这里放一些公共函数库,第三方支付模块以及我们的自定义验证类等等。上代码:

    app\Providers\MyValidator.php

    getValue($parameters[0]) != '') ? false : true;
        }
    }
    

    App\Providers\AppServiceProvider

    resources\lang\en\validation.php

    'custom' => [
        'phone' => [
            'empty_with' => '只能填一个字段,不能同时',
        ],
    ],
    

    定义好验证类,这个类只是扩展了 Laravel的内置验证基类,想让我们的验证规则被 Laravel “承认”,必须进入 AppServiceProviderboot 方法启动载入。

    分析返回条件,想一想如果达不到上面的“需求”,那意味着:

    • 不输入手机号,输入邮箱
    • 不输入手机号,不输入邮箱
    • 两者都不输入

    满足这三个条件即为验证通过,那么取反后判断条件如上,大家不用纠结这个判断,着重看 $this->getValue($parameters[0]) 这个方法,参数数组 $parameters[0] 为对应第一个验证规则,类似 min:xxx, 这里是 empty_with:email,通过该参数获取 email 对应的值传入 getValue() 中再返回 bool 值。问题来了,为什么是 empty_with:email 不是 emptyWith:email 或其他的呢,其实框架内部已经为我们处理好了名称的对应的格式,我们自定义的验证类里的验证方法必须以 validate 开头然后接小驼峰命名,对应验证规则的名称就是下划线的方式。这点要牢记

    效果图就不放了,大家可以尝试下,这样,基本上我们单独自定义的验证类结构就比较清晰了,利用面向对象的方式抽离出独立的验证类,更符合单一职责原则,这里其实还可以优化,比如独立出一个 ValidationExtensionServiceProvider extends ServiceProvider:

    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 );
            } );
        }
    }   
    

    然后告诉 laravel 载入该服务,app/config/app.php 里添加进去。这样就更符合 Laravel Way 了。

    你可能感兴趣的:(Laravel 5x 自定义数据验证)