服务器端接口参数校验方法

一开始写接口时,参数校验各种if判断,一坨坨的,看的要吐了,以下是屎一般的代码示例:

        if (!array_key_exists("cconf_corp_id", $data)) {
            return_json(1, "缺少参数:cconf_corp_id!", null);
        }
        if (!array_key_exists("cconf_closing_time", $data)) {
            return_json(1, "缺少参数:cconf_closing_time!", null);
        }
        if (!array_key_exists("cconf_delivery_time", $data)) {
            return_json(1, "缺少参数:cconf_delivery_time!", null);
        }

区区三个参数的存在判断就写了9行,这还只是存在,如果再加上值范围、值长度、值内容等的判断,就更多了!



找了一番资料后,修改如下:

0必须参数)
 * @param integer $min 最小值(含)
 * @param integer $max 最大值(含)
 * @return mixed    成功: true, 失败: 抛出异常
 */
function check_array(&$data, $name, $necessary, $min = null, $max = null) {
    if (is_null($data)) {
        if (0 < $necessary) {
            throw new Exception($name . "参数缺失!");
        }
        return true;
    } else {
        if (0 > $necessary) {
            throw new Exception($name . "参数当前不允许存在!");
        }
    }
    $count = count($data);
    if (null !== $min and null === $max) {
        if ($count < $min) {
            throw new Exception($name . "元素数量超出限制,需大于等于$min!");
        }
    } elseif (null === $min and null !== $max) {
        if ($count > $max) {
            throw new Exception($name . "元素数量超出限制,需小于等于$max!");
        }
    } elseif (null !== $min and null !== $max) {
        if ($count < $min or $count > $max) {
            throw new Exception($name . "元素数量超出限制,大小范围为$min-$max!");
        }
    }
    return true;
}

/**
 * 小数校验
 * @param mixed $data 数据(数字或字符串,字符串最后会被转换成数字)
 * @param string $name 参数名称
 * @param integer $necessary 是否必须参数(<0禁用参数, =0可有可无, >0必须参数)
 * @param integer $min 最小值(含)
 * @param integer $max 最大值(含)
 * @param integer $decimal_min 最小小数位数
 * @param integer $decimal_max 最大小数位数
 * @return mixed    成功: true, 失败: 抛出异常
 */
function check_decimal(&$data, $name, $necessary, $min = null, $max = null, $decimal_min = 0, $decimal_max = 2) {
    if (is_null($data)) {
        if (0 < $necessary) {
            throw new Exception($name . "参数缺失!");
        }
        return true;
    } else {
        if (0 > $necessary) {
            throw new Exception($name . "参数当前不允许存在!");
        }
    }
    $filter = "/^[+-]{0,1}[\\d]{1,}[.]{0,1}[\\d]{" . $decimal_min . "," . $decimal_max . "}$/";
    if (!preg_match($filter, strval($data))) {
        throw new Exception($name . "需为数字(小数点后$decimal_min-$decimal_max" . "位)!");
    }
    $data = floatval($data);
    if (null !== $min and null === $max) {
        if ($data < $min) {
            throw new Exception($name . "数值大小超出限制,需大于等于$min!");
        }
    } elseif (null === $min and null !== $max) {
        if ($data > $max) {
            throw new Exception($name . "数值大小超出限制,需小于等于$max!");
        }
    } elseif (null !== $min and null !== $max) {
        if ($data < $min or $data > $max) {
            throw new Exception($name . "数值大小超出限制,大小范围为$min-$max!");
        }
    }
    return true;
}

/**
 * 长整数校验
 * @param mixed $data 数据(数字或字符串,字符串最后会被转换成数字)
 * @param string $name 参数名称
 * @param integer $necessary 是否必须参数(<0禁用参数, =0可有可无, >0必须参数)
 * @param integer $min 最小值(含)
 * @param integer $max 最大值(含)
 * @return mixed    成功: true, 失败: 抛出异常
 */
function check_long(&$data, $name, $necessary, $min = null, $max = null) {
    if (is_null($data)) {
        if (0 < $necessary) {
            throw new Exception($name . "参数缺失!");
        }
        return true;
    } else {
        if (0 > $necessary) {
            throw new Exception($name . "参数当前不允许存在!");
        }
    }
    if (!preg_match("/^[+-]{0,1}[\\d]{1,}$/", strval($data))) {
        throw new Exception($name . "需为整数数字!");
    }
    $data = intval($data);
    if (null !== $min and null === $max) {
        if ($data < $min) {
            throw new Exception($name . "数值大小超出限制,需大于等于$min!");
        }
    } elseif (null === $min and null !== $max) {
        if ($data > $max) {
            throw new Exception($name . "数值大小超出限制,需小于等于$max!");
        }
    } elseif (null !== $min and null !== $max) {
        if ($data < $min or $data > $max) {
            throw new Exception($name . "数值大小超出限制,大小范围为$min-$max!");
        }
    }
    return true;
}

/**
 * 字符串校验
 * @param string $data 数据
 * @param string $name 参数名称
 * @param integer $necessary 是否必须参数(<0禁用参数, =0可有可无, >0必须参数)
 * @param integer $min 长度最小值(含)
 * @param integer $max 长度最大值(含)
 * @param boolean $number 是否包含数字(0不包含,1包含)
 * @param integer $letter 是否包含字母(0不包含,1包含小写,2包含大写,3包含大小写)
 * @param boolean $chinese 是否包含中文(0不包含,1包含)
 * @param string $symbol 包含符号(null不包含, "all"包含所有符号,包含个别符号如: ",.?/;")
 * @return mixed    成功: true, 失败: 抛出异常
 */
function check_string(&$data, $name, $necessary, $min = 0, $max = 0, $number = true, $letter = 3, $chinese = true, $symbol = null) {
    if (is_null($data)) {
        if (0 < $necessary) {
            throw new Exception($name . "参数缺失!");
        }
        return true;
    } else {
        if (0 > $necessary) {
            throw new Exception($name . "参数当前不允许存在!");
        }
    }
    $data = trim($data);
    if (strlen($data) < $min or strlen($data) > $max) {
        throw new Exception($name . "($data)长度超出限制,长度范围为$min-$max!");
    }

    $format = array();
    $number_filter = "";
    if (true === $number) {
        $number_filter = "0-9";
        array_push($format, "数字");
    }
    $letter_filter = "";
    if (1 === $letter) {
        $letter_filter = "a-z";
        array_push($format, "小写字母");
    } elseif (2 === $letter) {
        $letter_filter = "A-Z";
        array_push($format, "大写字母");
    } elseif (3 === $letter) {
        $letter_filter = "a-zA-Z";
        array_push($format, "大小写字母");
    }
    $chinese_filter = "";
    if (true === $chinese) {
        $chinese_filter = "\x7f-\xff";
        array_push($format, "汉字");
    }
    $symbol_filter = "";
    if (null !== $symbol) {
        if ("all" === $symbol) {
            $symbol_filter = "~!@#$%^&*()_+-={}|\ [\ ]\\:\";'<>?,.\/!¥…()—【】、:“”;’《》?,。\s";
        } else {
            $symbol_filter = $symbol;
        }
        array_push($format, "'$symbol'符号");
    }

    $filter = "/^[" . $symbol_filter . $number_filter . $letter_filter . $chinese_filter . "]{" . $min . "," . $max . "}$/";
    if (!preg_match($filter, $data)) {
        throw new Exception($name . "($data)格式不正确! 只可包含" . implode("、", $format) . "!");
    }

    return true;
}

/**
 * 日期校验
 * @param string $data 数据
 * @param string $name 参数名称
 * @param integer $necessary 是否必须参数(<0禁用参数, =0可有可无, >0必须参数)
 * @return mixed    成功: true, 失败: 抛出异常
 */
function check_date(&$date, $name, $necessary) {
    if (is_null($date)) {
        if (0 < $necessary) {
            throw new Exception($name . "参数缺失!");
        }
        return true;
    } else {
        if (0 > $necessary) {
            throw new Exception($name . "参数当前不允许存在!");
        }
    }

    $check = true;
    try {
        check_string($date, $name, $necessary, 10, 10, true, 0, false, "-");
    } catch (Exception $e) {
        $check = false;
    }

    if (false === date_create($date) or false === $check) {
        throw new Exception("$name($date)日期格式需为: 2016-01-01!");
    }

    return true;
}

/**
 * 电话校验
 * @param string $telephone 客户电话号码
 * @param integer $necessary 是否必须参数(<0禁用参数, =0可有可无, >0必须参数)
 * @return mixed    成功: true
 */
function check_telephone(&$telephone, $necessary) {
    if (is_null($telephone)) {
        if (0 < $necessary) {
            throw new Exception("电话号码为空!");
        }
        return true;
    } else {
        if (0 > $necessary) {
            throw new Exception("电话号码参数当前不允许存在!");
        }
    }
    $telephone = trim($telephone);
    if (!preg_match("/^(0[0-9]{2,3}(-)?)?([2-9][0-9]{6,7})(-[0-9]{1,4})?$|^(?:400|800)[0-9]{7}$/", $telephone)) {
        throw new Exception("无效的电话号码: $telephone!");
    }

    return true;
}

/**
 * 手机校验
 * @param string $mobile 客户手机号
 * @param integer $necessary 是否必须参数(<0禁用参数, =0可有可无, >0必须参数)
 * @return mixed    成功: true
 */
function check_mobile(&$mobile, $necessary) {
    if (is_null($mobile)) {
        if (0 < $necessary) {
            throw new Exception("手机号为空!");
        }
        return true;
    } else {
        if (0 > $necessary) {
            throw new Exception("手机号参数当前不允许存在!");
        }
    }
    $mobile = trim($mobile);
    if (!preg_match("/^13[0-9]{9}$|^15[012356789]{1}[0-9]{8}$|^18[0-9]{9}$|^17[678][0-9]{8}$|^14[57][0-9]{8}$/", $mobile)) {
        throw new Exception("无效的手机号: $mobile!");
    }
    return true;
}

/**
 * 微信校验
 * @param string $wx_id 客户微信号
 * @param integer $necessary 是否必须参数(<0禁用参数, =0可有可无, >0必须参数)
 * @return mixed    成功: true
 */
function check_wechat(&$wx_id, $necessary) {
    if (is_null($wx_id)) {
        if (0 < $necessary) {
            throw new Exception('微信号为空!');
        }
        return true;
    } else {
        if (0 > $necessary) {
            throw new Exception('微信号参数当前不允许存在!');
        }
    }
    $wx_id = trim($wx_id);
    if (!preg_match('/^[a-zA-Z][a-zA-Z0-9_-]{5,}$/', $wx_id)) {
        throw new Exception("无效的微信号: $wx_id!");
    }
    return true;
}

/**
 * 邮箱校验
 * @param string $email 客户邮箱
 * @param integer $necessary 是否必须参数(<0禁用参数, =0可有可无, >0必须参数)
 * @return mixed    成功: true, 失败: string
 */
function check_email(&$email, $necessary) {
    if (is_null($email)) {
        if (0 < $necessary) {
            throw new Exception('邮箱为空!');
        }
        return true;
    } else {
        if (0 > $necessary) {
            throw new Exception('邮箱参数当前不允许存在!');
        }
    }
    $email = trim($email);
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        throw new Exception("无效的邮箱: $email!");
    }
    return true;
}

/**
 * 返回json字符串给接口调用者
 * @param integer   $code   错误码
 * @param string    $msg    错误信息
 * @param string    $data   输出数据
 */
function return_json($code, $msg = null, $data = null) {
    $ret = array("errcode" => $code,);
    $ret["errmsg"] = ($msg === null) ? "" : $msg;
    $ret["data"] = ($data === null) ? "" : $data;
    echo json_encode($ret, JSON_UNESCAPED_UNICODE);
    exit();
}

try {
    check_date($data["date"], "date", 1);
    check_long($data["order_id"], "order_id", 1, 1);
    check_string($data["content"], "content", 1, 0, 140, true, 3, true, "all");
    check_array($data["skus"], "skus", 1, 1);
    foreach ($data["skus"] as $sku) {
        check_long($sku["publish_id"], "publish_id", 1, 1);
        check_long($sku["num"], "num", 1, 1);
    }
} catch (Exception $e) {
    return_json(1, $e->getMessage(), null);
}

注:177行中列举的符号,由于编辑器不支持,加了两个空格,实际使用中要去除


如上


若有更好的方式,欢迎指证!






你可能感兴趣的:(PHP,服务端)