利用反射动态验证方法调用方法

验证规则

基于Webmozart Assert封装的验证,利用反射简化了原有的调用过程,增加了语言包,自定义验证规则

基本使用

//验证规则
$rule = [
          //字符串方式  '验证的字段'=>'规则1|规则2:参数1|规则3:参数1:参数2'
          'category_num'  =>'notEmpty|eq:10|lengthBetween:1:3',
          //数组方式
            'category_name' => [  //验证的字段
                'notEmpty',//规则1
                'eq'        => [ //规则2
                    10, //参数1
                ],
                'lengthBetween' => [ //规则3
                    1, //参数1
                    3, //参数2
                ],
            ],
        ];
//自定义message,如果没有自定义,就默认读语言包的
$msg =[
        'category_num.notEmpty'=>'必填'
      ];
      //调用验证
  (new  Validator())->v($this->in, $rule);
复制代码

语言包

语言包文件是lang/zh-cn.php(框架自带或者任意配置文件)

   'notEmpty'  => '请填写%s', //%s代表替换字段
   'eq'        => '', 如果默认消息为空,可以自定义添加
复制代码

自定义验证规则

在Ext目录下新建或者在已有的trait里新增方法方法名必须是唯一的,不能跟现有的重复,方法名即验证规则

trait Test
{
    //第一个参数,必须是$val,这个参数就是字段的值,最后一个参数必须是$message 就是消息,中间可以自定义参数,没有限制个数
    public function testValidator($val,$min,$message='')
    {
        if($val>0){
            throw new \InvalidArgumentException($message);
        }
    }
}
复制代码

已有的验证规则可以查看github.com/webmozart/a…上面的

反射

是指在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类、方法、属性、参数等的详细信息,包括注释。这种动态获取的信息以及动态调用对象的方法的功能称为反射API。 反射是操纵面向对象范型中元模型的API,其功能十分强大,可帮助我们构建复杂,可扩展的应用

其用途如:自动加载插件,自动生成文档,甚至可用来扩充PHP语言。

本人比较懒就直接贴代码了、、、、、、、

目录结构

.
+-- Validator.class.php
+-- ValidatorExt.class.php
+-- Ext
|   +-- Test.class.php
|   +-- header.html
复制代码

Validator

<?php

namespace RestfulApi\Common\Validator;

use Webmozart\Assert\Assert;

/**
 * 验证
 * Class Validator
 * @package RestfulApi\Common\Validator
 * @author matao
 * @since 2018-08-01
 */
class Validator
{
    /**
     *  验证
     * @param $data
     * @param $rules
     * @param array $msg
     * @return bool
     * @throws \ReflectionException
     * @author matao
     * @since 2018-08-01
     */
    public function v($datas, $rules, $msg = [])
    {
        //转化验证规则
        $rule = $this->formatRule($rules);
        //转化值
        $data = $this->conversion($datas, $rules);
        //验证
        $this->validator($data, $rule, $msg);
        
        return true;
    }
    
    /**
     * 格式化rule
     * @param $rules
     * @return array
     * @author matao
     * @since 2018-08-01
     */
    private function formatRule($rules)
    {
        $rule = [];
        foreach ($rules as $key => $value) {
            if (is_string($value)) {
                $tmp         = explode('|', $value);
                $currentRule = [];
                foreach ($tmp as $t) {
                    $subRule = explode(':', $t);
                    if (is_array($subRule) && count($subRule) > 1) {
                        $K = $subRule[0];
                        unset($subRule[0]);
                        $currentRule[$K] = array_values($subRule);
                    } else {
                        $currentRule[] = $subRule[0];
                    }
                    
                }
                $rule[$key] = $currentRule;
            } else {
                $rule[$key] = $value;
            }
        }
        
        return $rule;
    }
    
    /**
     * data转换
     * @param $datas
     * @param $rules
     * @return array
     * @author matao
     * @since 2018-08-07
     */
    private function conversion($datas, $rules)
    {
        $allKey = array_keys($rules);
        $allKey = array_fill_keys($allKey, null);
        
        return array_merge($allKey, $datas);
    }
    
    /**
     * 执行验证
     * @param $data
     * @param $rule
     * @param array $msg
     * @throws \ReflectionException
     * @author matao
     * @since 2018-08-01
     */
    private function validator($data, $rule, $msg = [])
    {
        foreach ($data as $key => $datum) {
            if (!isset($rule[$key])) {
                break;
            }
            foreach ($rule[$key] as $k => $value) {
                
                if (is_array($value)) {
                    $param = $value;
                    array_unshift($param, $datum);
                    $method = $k;
                } else {
                    $param[] = $datum;
                    $method  = $value;
                    
                }
                $message = '';
                //如果有自定义message就使用
                if (!empty($msg["{$key}.{$method}"])) {
                    $message = $msg["{$key}.{$method}"];
                } elseif (L($method)) {   //L($method) 是获取方法对应的message
                    $message = sprintf(L($method), $key);  //用当前字段字段替换%s ,%s代表输出的是字符串
                }
                $param[] = $message ?: '';  //$param是该方法的参数[$val1,$val2]
                //调用具体的方法
                $this->scheduler($method, $param);
                unset($param);
            }
        }
        
    }
    
    /**
     * 调度
     * @param $method
     * @param $param
     * @throws \ReflectionException
     * @author matao
     * @since 2018-08-01
     */
    private function scheduler($method, $param)
    {
        $base = new Assert();
        //没有找到Webmozart Assert里的方法就使用自定义的
        if ($this->reflection($base, $method, $param) === false) {
            $ext = new ValidatorExt();
            $this->reflection($ext, $method, $param);
        }
    }
    
    /**
     * 反射
     * @param $class
     * @param $method
     * @param $param
     * @return bool
     * @throws \ReflectionException
     * @author matao
     * @since 2018-08-01
     */
    public function reflection($class, $method, $param)
    {
        //放入要反射的类
        $reflectionClass = new \ReflectionClass($class);
        //查找是否存在该方法
        $isMethod = $reflectionClass->hasMethod($method);
        if ($isMethod === true) {
            //获取类方法
            $reflectionMethod   = $reflectionClass->getMethod($method);
            //从指定的参数创建一个新的类实例
            $reflectionInstance = $reflectionClass->newInstance($param);
            //放入参数并调用该方法
            $reflectionMethod->invokeArgs($reflectionInstance, $param);
            
            return true;
        }
        
        return false;
        
    }
}
复制代码

ValidatorExt 自定义方法

<?php

namespace RestfulApi\Common\Validator;

//自定义验证,方法不能跟已有的重复
use RestfulApi\Common\Validator\Ext\MySQLValidator;
use RestfulApi\Common\Validator\Ext\Test;

class ValidatorExt
{
    use Test, MySQLValidator;
    
    public function __construct()
    {
    
    }
}
复制代码

testValidator

<?php



namespace RestfulApi\Common\Validator\Ext;

trait Test
{
    public function testValidator($val,$message='')
    {
        if($val>0){
        //抛出错误
            throw new \InvalidArgumentException($message);
        }
    }
}
复制代码

捕获抛出的异常

  set_exception_handler(function (\InvalidArgumentException $exception) {
           ##########################随意发挥#############################
        });
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值