一个简易的过滤获取参数的方法

<?php

/**
 * 字段过滤方法 (简易)
 * 用法:
 * $rules = [
 *      'id' => Filter::filterRule(Filter::FILTER_NUM,'平台id',true,100),
 * ];
 * Filter::doc($rules);die;//打印接口参数文档
 * //过滤获取数据
 * list($params,$err) = Filter::filterParams($rules,$input);
 * //使用
 * echo $params['id'];
 */

namespace Mt\Util;

class Filter
{
    //原生
    const FILTER_RAW = 0;
    //数字
    const FILTER_NUM = 1;
    //字符串
    const FILTER_STR = 2;
    //json
    const FILTER_JSON = 3;
    //日期 2019-04-02 19:08:37
    const FILTER_DATE = 4;
    //枚举
    const FILTER_ENUM = 5;
    //日期 20190412
    const FILTER_DATE_YMD = 6;
    //逗号分隔数字
    const FILTER_COMMA_SEP_NUM = 7;
    //逗号分隔字符串
    const FILTER_COMMA_SEP_STR = 8;

    //类型
    const RULE_TYPE = 0;
    //是否必填
    const RULE_REQUIRED = 1;
    //默认值
    const RULE_DEFAULT = 2;
    //描述
    const RULE_DESC = 3;
    //字符限制
    const RULE_LIMIT_MAX = 4;
    const RULE_LIMIT_MIN = 5;
    //自定义错误信息
    const RULE_MSG = 6;

    /**
     * 过滤规则
     * @param $type 参数类型 数字,字符串,原生,json
     * @param bool $required 是否必须
     * @param null $default 默认值
     * @param null $limit 宽字限制,格式:6-16
     * @return array
     */

    public static function filterRule($type,$desc,$required = false,$default = null,$limit=null,$msg = null) {
        $max = $min = null;
        if (!empty($limit)) {
            $limitOpt = explode('-',$limit);
            if (count($limitOpt)==2) {
                $min = intval($limitOpt[0]);
                $max = intval($limitOpt[1]);
            } else if (count($limitOpt)==1){
                $max = intval($limitOpt[0]);
            }
        }
        return [
            self::RULE_TYPE=>$type,
            self::RULE_DESC=>$desc,
            self::RULE_REQUIRED=>$required,
            self::RULE_DEFAULT=>$default,
            self::RULE_LIMIT_MAX=>$max,
            self::RULE_LIMIT_MIN=>$min,
            self::RULE_LIMIT_MIN=>$min,
            self::RULE_MSG=>$msg,
        ];
    }

    /**
     * 过滤参数
     * @param $rules 过滤规则集合
     * @param $input 输入数据
     * @return array 输出数据
     */
    public static function filterParams($rules,$input) {
//        $rules = [
//            //type,required,default,
//            'id' => array(self::FILTER_NUM, 1, 0)
//        ];

        $params = [];

        foreach ($rules as $k => $rule) {
            if (isset($input[$k])) {
                if (!isset($rule[self::RULE_TYPE])) {
                    return [[], sprintf('参数获取规则错误')];
                }
                //原生
                if ( $rule[self::RULE_TYPE] == self::FILTER_RAW) {
                    $params[$k] = $input[$k];
                }
                //数字类型
                if ( $rule[self::RULE_TYPE] == self::FILTER_NUM) {
                    if (is_numeric($input[$k])) {
                        if (is_float($input[$k]+0)) {
                            $params[$k] = floatval($input[$k]);
                        } else if (is_int($input[$k]+0)) {
                            $params[$k] = intval($input[$k]);
                        } else {
                            $params[$k] = $input[$k];
                        }
                    } else {
                        if ($rule[self::RULE_MSG] != null && !empty($rule[self::RULE_MSG])) {
                            $err = $rule[self::RULE_MSG];
                        } else {
                            $err = sprintf('%s字段类型必须为数字', $k);
                        }
                        return [[], $err];
                    }
                }
                //字符串类型,会htmlspecialchars过滤
                if ( $rule[self::RULE_TYPE] == self::FILTER_STR) {
                    if (is_string($input[$k])) {
                        $params[$k] = htmlspecialchars($input[$k]);
                    } else {
                        if ($rule[self::RULE_MSG] != null && !empty($rule[self::RULE_MSG])) {
                            $err = $rule[self::RULE_MSG];
                        } else {
                            $err = sprintf('%s字段类型必须为字符串', $k);
                        }
                        return [[], $err];
                    }
                }
                //json 类型 符合会转换成字符串
                if ( $rule[self::RULE_TYPE] == self::FILTER_JSON) {
                    if (is_string($input[$k])) {
                        $param = json_decode($input[$k],true);
                        if (json_last_error() !== 0) {
                            if ($rule[self::RULE_MSG] != null && !empty($rule[self::RULE_MSG])) {
                                $err = $rule[self::RULE_MSG];
                            } else {
                                $err = sprintf('%s字段类型必须为json字符串格式', $k);
                            }
                            return [[], $err];
                        }
                        $params[$k] = $param;
                    } else {
                        if ($rule[self::RULE_MSG] != null && !empty($rule[self::RULE_MSG])) {
                            $err = $rule[self::RULE_MSG];
                        } else {
                            $err = sprintf('%s字段类型必须为字符串', $k);
                        }
                        return [[], $err];
                    }
                }
                //date类型
                if ( $rule[self::RULE_TYPE] == self::FILTER_DATE) {
                    if (!is_string($input[$k]) || date('Y-m-d H:i:s',strtotime($input[$k])) != $input[$k]) {
                        if ($rule[self::RULE_MSG] != null && !empty($rule[self::RULE_MSG])) {
                            $err = $rule[self::RULE_MSG];
                        } else {
                            $err = sprintf('%s字段类型必须为日期格式yyyy-MM-dd HH:mm:ss', $k);
                        }
                        return [[], $err];
                    }
                    $params[$k] = $input[$k];
                }
                //date ymd类型
                if ( $rule[self::RULE_TYPE] == self::FILTER_DATE_YMD) {
                    if (!is_string($input[$k]) || date('Ymd',strtotime($input[$k])) != $input[$k]) {
                        if ($rule[self::RULE_MSG] != null && !empty($rule[self::RULE_MSG])) {
                            $err = $rule[self::RULE_MSG];
                        } else {
                            $err = sprintf('%s字段类型必须为日期格式yyyyMMdd', $k);
                        }
                        return [[], $err];
                    }
                    $params[$k] = $input[$k];
                }
                if ( $rule[self::RULE_TYPE] == self::FILTER_ENUM) {
                    if (!is_array($rule[self::RULE_DEFAULT])
                        || empty($rule[self::RULE_DEFAULT]) || is_null($rule[self::RULE_DEFAULT])) {
                        return [[], sprintf('%s字段枚举类型默认值必须为一维关联数组,即枚举值',$k)];
                    }
                    if (!in_array($input[$k],$rule[self::RULE_DEFAULT])) {
                        if ($rule[self::RULE_MSG] != null && !empty($rule[self::RULE_MSG])) {
                            $err = $rule[self::RULE_MSG];
                        } else {
                            $err = sprintf('%s值为非枚举[%s]中元素',$k,join(',',$rule[self::RULE_DEFAULT]));
                        }
                        return [[], $err];
                    }
                    $params[$k] = $input[$k];
                }
                //逗号分隔数字
                if ( $rule[self::RULE_TYPE] == self::FILTER_COMMA_SEP_NUM) {
                    $arr = [];
                    if (is_numeric($input[$k])) {
                        $arr[] = $input[$k];
                    } else if (is_string($input[$k]) && !empty($input[$k])) {
                        $arr2 = explode(',',$input[$k]);
                        foreach ($arr2 as $v){
                            if (is_numeric($v)) {
                                if (is_float($v+0)) {
                                    $arr[] = floatval($v);
                                } else if (is_int($v+0)) {
                                    $arr[] = intval($v);
                                } else {
                                    $arr[] = $v;
                                }
                            } else {
                                $err = sprintf('%s值存在非数字类型',$k,join(',',$arr2));
                                return [[], $err];
                            }
                        }
                    }
                    $params[$k] = $arr;
                }
                //逗号分隔字符串
                if ( $rule[self::RULE_TYPE] == self::FILTER_COMMA_SEP_STR) {
                    $arr = [];
                    if (is_string($input[$k]) && !empty($input[$k])) {
                        $arr2 = explode(',',$input[$k]);
                        foreach ($arr2 as $v){
                            if (is_string($v) || is_numeric($v)) {
                                $arr[] = htmlspecialchars($v);
                            } else {
                                $err = sprintf('%s值存在非字符串类型',$k,join(',',$arr2));
                                return [[], $err];
                            }
                        }
                    }
                    $params[$k] = $arr;
                }
            } else {
                if ($rule[self::RULE_REQUIRED] === true || $rule[self::RULE_REQUIRED] === 1) {
                    if ($rule[self::RULE_MSG] != null && !empty($rule[self::RULE_MSG])) {
                        $err = $rule[self::RULE_MSG];
                    } else {
                        $err = sprintf('%s字段为必须项', $k);
                    }
                    return [[], $err];
                } else {
                    if (isset($rule[self::RULE_DEFAULT])) {
                        if (is_array($rule[self::RULE_DEFAULT]) && !empty($rule[self::RULE_DEFAULT])) {
//                            $params[$k] = $rule[self::RULE_DEFAULT][0];
                        } else {
                            $params[$k] = $rule[self::RULE_DEFAULT];
                        }
                    }
                }
            }
            if ($rule[self::RULE_LIMIT_MAX] !== null) {
                if (mb_strlen($params[$k]) > $rule[self::RULE_LIMIT_MAX]){
                    if ($rule[self::RULE_MSG] != null && !empty($rule[self::RULE_MSG])) {
                        $err = $rule[self::RULE_MSG];
                    } else {
                        $err = sprintf('%s字段,最大限制%d字符', $k,$rule[self::RULE_LIMIT_MAX]);
                    }
                    return [[], $err];
                }
            }
            if ($rule[self::RULE_LIMIT_MIN] !== null) {
                if (mb_strlen($params[$k]) < $rule[self::RULE_LIMIT_MIN]){
                    if ($rule[self::RULE_MSG] != null && !empty($rule[self::RULE_MSG])) {
                        $err = $rule[self::RULE_MSG];
                    } else {
                        $err = sprintf('%s字段,最小限制%d字符', $k,$rule[self::RULE_LIMIT_MIN]);
                    }
                    return [[], $err];
                }
            }
        }
        return [$params,null];
    }

    /**
     * 仅限开发打印文档用markdown
     * @param $rules
     */
    public static function doc($rules) {
        $ruleTypes = [
            self::FILTER_RAW => 'raw',
            self::FILTER_NUM => 'num',
            self::FILTER_STR => 'string',
            self::FILTER_JSON => 'json',
            self::FILTER_DATE => 'datetime',
            self::FILTER_DATE_YMD => 'datetime(yyyMMdd)',
        ];
        echo "\r\n";
        echo sprintf("%s\r\n",'|参数名字|参数类型|说明|是否必填|');
        echo sprintf("%s\r\n",'|:--|:--|:--|:--|');
        foreach ($rules as $k =>$rule) {
            $type = $ruleTypes[$rule[self::RULE_TYPE]];
            if ($rule[self::RULE_TYPE] == self::FILTER_ENUM) {
                $type = sprintf("enum(%s)",join(',',$rule[self::RULE_DEFAULT]));
            }
            $required = $rule[self::RULE_REQUIRED]?'Y':'N';
            $desc = $rule[self::RULE_DESC];
            echo sprintf("| %s | %s | %s | %s |\r\n",$k,$type,$desc,$required);
        }

    }
}

发表新评论