laravel之验证器


开发中使用框架自带验证器进行参数验证

1.定义验证器基类,定义失败返回值

新建基础类文件 app > Http > Requests > BaseRequest.php

<?php 
    namespace App\Http\Requests;
    use Illuminate\Foundation\Http\FormRequest;
    use Illuminate\Contracts\Validation\Validator;
    use Illuminate\Http\Exceptions\HttpResponseException;

    class BaseRequest extends FormRequest
    {
        protected function failedValidation(Validator $validator) {
            $error= $validator->errors()->all();
            throw new HttpResponseException(response()->json(['msg'=>'error','code'=>'500','data'=>$error[0]], 500));
        }
    }
?>

这里验证器继承BaseRequest.php

2.多场景验证

1)封装验证基类BaseValidate.php, 放置在app\Validate下, 其他地方也是OK的

<?php
namespace App\Validate;

use Illuminate\Support\Facades\Validator;
/**
 * 扩展验证器
 */
class BaseValidate {

    /**
     * 当前验证规则
     * @var array
     */
    protected $rule = [];

    /**
     * 验证提示信息
     * @var array
     */
    protected $message = [];

    /**
     * 验证场景定义
     * @var array
     */
    protected $scene = [];

    /**
     * 设置当前验证场景
     * @var array
     */
    protected $currentScene = null;

    /**
     * 验证失败错误信息
     * @var array
     */
    protected $error = [];

    /**
     * 场景需要验证的规则
     * @var array
     */
    protected $only = [];


    /**
     * 设置验证场景
     * @access public
     * @param  string  $name  场景名
     * @return $this
     */
    public function scene($name)
    {
        // 设置当前场景
        $this->currentScene = $name;

        return $this;
    }

    /**
     * 数据验证
     * @access public
     * @param  array     $data  数据
     * @param  mixed     $rules  验证规则
     * @param  array    $message 自定义验证信息
     * @param  string    $scene 验证场景
     * @return bool
     */
    public function check($data, $rules = [], $message = [],$scene = '')
    {
        $this->error =[];
        if (empty($rules)) {
            //读取验证规则
            $rules = $this->rule;
        }
        if (empty($message)) {
            $message = $this->message;
        }

        //读取场景
        if (!$this->getScene($scene)) {
            return false;
        }

        //如果场景需要验证的规则不为空
        if (!empty($this->only)) {
            $new_rules = [];
            foreach ($this->only as $key => $value) {
                if (array_key_exists($value,$rules)) {
                    $new_rules[$value] = $rules[$value];
                }    
            }
            $rules = $new_rules;
        }
        // var_dump($rules);die;
        $validator = Validator::make($data,$rules,$message);
        //验证失败
        if ($validator->fails()) {
            $this->error = $validator->errors()->first();
            return false;
        }

        return !empty($this->error) ? false : true;
    }

    /**
     * 获取数据验证的场景
     * @access protected
     * @param  string $scene  验证场景
     * @return void
     */
    protected function getScene($scene = '')
    {
        if (empty($scene)) {
            // 读取指定场景
            $scene = $this->currentScene;
        }
        $this->only = [];

        if (empty($scene)) {
            return true;
        }

        if (!isset($this->scene[$scene])) {
            //指定场景未找到写入error
            $this->error = "scene:".$scene.'is not found';
            return false;
        }
        // 如果设置了验证适用场景
        $scene = $this->scene[$scene];
        if (is_string($scene)) {
            $scene = explode(',', $scene);
        }
        //将场景需要验证的字段填充入only
        $this->only = $scene;
        return true;
    }

    // 获取错误信息
    public function getError()
    {
        return $this->error;
    }



}

  2)使用 ArticleValidate.php

<?php
namespace App\Validate;

use App\Validate\BaseValidate;
/**
 * 文章验证器
 */
class ArticleValidate extends BaseValidate {
    //验证规则
    protected $rule =[
        'id'=>'required',
        'title' => 'required|max:255',
        'content' => 'required',
    ];
    //自定义验证信息
    protected $message = [
        'id.required'=>'缺少文章id',
        'title.required'=>'请输入title',
        'title.max'=>'title长度不能大于 255',
        'content.required'=>'请输入内容',
    ];

    //自定义场景
    protected $scene = [
        'add'=>"title,content",
        'edit'=> ['id','title','content'],
    ];
}

rule: 定义规则

message: 定义验证信息

scene: 验证场景

3) 非场景验证方式

public function update(){

        $ArticleValidate = new ArticleValidate;

        $request_data = [
            'id'=>'1',
            'title'=>'我是文章的标题',
            'content'=>'我是文章的内容',
        ];

        if (!$ArticleValidate->check($request_data)) {
           var_dump($ArticleValidate->getError());
        }

    }

check 方法中总共有四个参数,第一个要验证的数据,第二个验证规则,第三个自定义错误信息,第四个验证场景,其中 2,3,4 非必传。
如果验证未通过我们调用 getError() 方法来输出错误信息,getError()暂不支持返回所有验证错误信息 。

4)控制器中使用

public function add(){

        $ArticleValidate = new ArticleValidate;

        $request_data = [
            'title'=>'我是文章的标题',
            'content'=>'我是文章的内容',
        ];

        if (!$ArticleValidate->scene('add')->check($request_data)) {
           var_dump($ArticleValidate->getError());
        }

    }

5)控制器内验证

public function add(){

        $Validate = new BaseValidate;

        $request_data = [
            'title'=>'我是文章的标题',
            'content'=>'我是文章的内容',
        ];

        $rule =[
            'id'=>'required',
            'title' => 'required|max:255',
            'content' => 'required',
        ];
        //自定义验证信息
        $message = [
            'id.required'=>'缺少文章id',
            'title.required'=>'请输入title',
            'title.max'=>'title长度不能大于 255',
            'content.required'=>'请输入内容',
        ];

        if (!$Validate->check($request_data,$rule,$message)) {
           var_dump($Validate->getError());
        }

    }

通过验证场景,既减少了控制器代码的臃肿,又减少了 FormRequest 文件过多,还可以自定义 json 数据