lumen验证类 实现控制器场景验证

Laravel框架
397
0
0
2022-11-11

创建 app\Http\Requests\ValidatorTrait.php trait

<?php

namespace App\Http\Validators;

use Illuminate\Support\Facades\Validator;

trait ValidatorTrait
{
    /**
     * 场景名称
     * @var null
     */ 
    protected $scene = null;
    /**
     * 只验证的规则
     * @var array
     */ 
    protected $onlyRule=[];

    protected static $obj=null;

    /**
     * 自定义错误消息
     * @var array
     */ 
    protected $massage=[
        "required"    => ":attribute 不能为空",
        "required_if"    => ":attribute 不能为空",
        "required_unless"    => ":attribute 不能为空",
        "required_with"    => ":attribute 不能为空",
        "between"     => [
            'string'=>":attribute 长度必须在 :min 和 :max 之间",
            'numeric'=>":attribute 必须在 :min 和 :max 之间",
        ],
        "email"       => ":attribute 格式错误",
        "regex"       => ":attribute 格式错误",
        "mobile"      => ":attribute 格式错误",
        'date_format' => ':attribute 与给定的格式 :format 不符合',
        'unique'      => ':attribute 已存在',
        'min'         => ':attribute 最小长度为 :min 位',
        'max'         => ':attribute 最大长度为 :max 字符',
        'in'          => ':attribute 不在操作范围',
        "numeric"     => ":attribute 不为数字",
        "integer"     => ":attribute 不为整数",
        "string"      => ":attribute 不为字符串",
        "date"      => ":attribute 格式错误",
        "after"      => ":attribute 大于 :date",
        "gt"      => ":attribute 需大于 :value",
        "exists"      => ":attribute 数据有误",
        "point"      => ":attribute 只能保留小数点后 :num 位",
        "digits"      => ":attribute 长度为 :digits 位",
        "digits_between"      => ":attribute 长度为 :min 和 :max 之间",
    ];


    /**
     * @return mixed
     */ 
    protected function makeValidator()
    {
        $validationData = app('request');
        $validator = Validator::make(
            $validationData->all(),
            $this->getRules(),
            $this->massage,
            method_exists($this,'attributes') ? $this->attributes() : []
        );
        if ($validator->fails()) {
            return $this->failedValidation($validator);
        }else{
            return $validationData;
        }
    }

    /**
     * 返回错误
     * @param $validator
     * @return mixed
     */ 
    public function failedValidation($validator)
    {
        return $validator->errors()->first();
    }


    /**
     * 验证方法
     * @param mixed $scene  场景名称或验证规则
     */ 
    public function make($scene='')
    {
        if(!(self::$obj instanceof self)){
            self::$obj = new self();
        }

        if(!empty($scene)){
            if(is_array($scene)){
                self::$obj->onlyRule = $scene;
            }else{
                self::$obj->scene = $scene;
            }
        }
        return self::$obj->makeValidator();
    }


    /**
     * 获取 rules
     * @return array
     */ 
    protected function getRules(): array
    {
        return $this->handleScene(method_exists($this,'rules') ? $this->rules() : []);
    }

    /**
     * 场景验证
     * @param array $rule
     * @return array
     */ 
    protected function handleScene(array $rule = []): array
    {
        if($this->onlyRule){
            return $this->handleRule($this->onlyRule,$rule);
        }
        $sceneName = $this->scene;
        if($sceneName && method_exists($this,'scene')){
            $scene = $this->scene();
            if(array_key_exists($sceneName,$scene)) {
                return $this->handleRule($scene[$sceneName],$rule);
            }
        }
        return  $rule;
    }

    /**
     * 处理Rule
     * @param array $sceneRule
     * @param array $rule
     * @return array
     */ 
    private function handleRule(array $sceneRule,array $rule): array
    {
        $rules = [];
        foreach ($sceneRule as $key => $value) {
            if (is_numeric($key) && array_key_exists($value,$rule)) {
                $rules[$value] = $rule[$value];
            } else {
                $rules[$key] = $value;
            }
        }
        return $rules;
    }
}

用法

在验证类内里 use ValidatorTrait

例如下面 TestValidator 验证类

<?php


namespace App\Http\Validators;



class TestValidator
{
    use ValidatorTrait;

    /**
     * 字段注解
     * @return array
     */ 
    public function attributes():array
    {
        return [
            'name'=>'姓名',
            'email'=>'邮件',
        ];
    }

    /**
     * 验证规则
     * @return array
     */ 
    public function rules():array
    {
        return [
            'name' => 'required|string|unique:users',
            'email' => 'required|email|unique:users',
        ];
    }

    /**
     * 验证场景
     * @return array
     */ 
    public function scene():array
    {
        return [
            //add 场景 
            'add' => [
                'name' ,       //复用 rules() 下 name 规则 
                'email' => 'email|unique:users'  //重置规则
            ],
            //edit场景 
            'edit' => ['name'],
        ];
    }

}

控制器验证

use App\Http\Validators\TestValidator;

public function add(Request $request){
    //验证所以的 
    dd(TestValidator::make());
    //验证 add 场景的字段 
    dd(TestValidator::make('add'));
    //验证当前字段或规则 
    dd(TestValidator::make(['id'=>['required'],'status']));
}