ThinkPHP实现一个复杂的参数验证器
2018-05-11 本文已影响0人
红烧排骨饭
需求
客户端传来这样一个 json 数据,服务端需要对数据进行验证。验证数据格式是否正确
{
"products": [
{
"product_id": 1,
"count": 3
},
{
"product_id": 2,
"count": 3
},
{
"product_id": 3,
"count": 3
}
]
}
在 ThinkPHP 5 中,如果使用一般的 Validate 无法实现,还需要另外写一个代码来实现。
数据格式
- products 是一个数组
- 数组元素的格式是 { "product_id": 1, "count": 3 }
代码实现
BaseValidate
<?php
namespace app\api\validate;
use app\lib\exception\ParameterException;
use think\Request;
use think\Validate;
class BaseValidate extends Validate
{
public function goCheck()
{
// 获取HTTP传入的参数
$params = Request::instance()->param();
// 对这些参数做校验
$result = $this->batch()->check($params);
if ($result) {
return true;
} else {
throw new ParameterException([
'msg' => $this->error
]);
}
}
/**
* 自定义验证规则:判断是否是正整数
*/
protected function isPositiveInteger($value, $rule = '', $data = '', $field = '')
{
if (is_numeric($value) &&
is_int($value + 0) &&
($value + 0) > 0) {
return true;
} else {
return false;
}
}
/**
* 不能为空
*/
protected function isNotEmpty($value, $rule = '', $data = '', $field = '')
{
if (empty($value)) {
return false;
} else {
return true;
}
}
}
OrderPlace
<?php
namespace app\api\validate;
use app\lib\exception\ParameterException;
/**
* 验证下单参数
*
* {
* "products": [
* {
* "product_id": 1,
* "count": 3
* },
* {
* "product_id": 2,
* "count": 3
* },
* {
* "product_id": 3,
* "count": 3
* }
* ]
* }
*/
class OrderPlace extends BaseValidate
{
protected $rule = [
'products' => 'checkProducts'
];
protected $singleRule = [
'product_id' => 'require|isPositiveInteger',
'count' => 'require|isPositiveInteger',
];
protected function checkProducts($values)
{
if (!is_array($values)) {
throw new ParameterException(
[
'msg' => '商品参数不正确'
]);
}
if (empty($values)) {
throw new ParameterException(
[
'msg' => '商品列表不能为空'
]);
}
foreach ($values as $value) {
$this->checkProduct($value);
}
return true;
}
protected function checkProduct($value)
{
$validate = new BaseValidate($this->singleRule);
$result = $validate->check($value);
if (!$result) {
throw new ParameterException([
'msg' => '商品列表参数错误',
]);
}
}
}
BaseException
<?php
namespace app\lib\exception;
use think\Exception;
/**
* 异常基类(由于用户行为导致的异常)
*/
class BaseException extends Exception
{
/**
* HTTP 状态码
*/
public $code = 400;
/**
* 错误信息
*/
public $msg = '参数错误';
/**
* 自定义的错误码
*/
public $errorCode = 10000;
public function __construct($params = [])
{
if (!is_array($params)) {
return;
}
if (array_key_exists('code', $params)) {
$this->code = $params['code'];
}
if (array_key_exists('msg', $params)) {
$this->msg = $params['msg'];
}
if (array_key_exists('errorCode', $params)) {
$this->errorCode = $params['errorCode'];
}
}
}
ParameterException
<?php
namespace app\lib\exception;
class ParameterException extends BaseException
{
public $code = 400;
public $msg = '参数错误';
public $errorCode = 10000;
}
使用
在 Controller 中使用
<?php
namespace app\api\controller\v1;
use app\api\controller\BaseController;
use app\api\validate\OrderPlace;
use app\api\service\Token as TokenService;
class Order extends BaseController
{
/**
* 下单
*/
public function placeOrder()
{
(new OrderPlace())->goCheck(); // 验证参数
// ...
}
}