美文网首页
ThinkPHP实现一个复杂的参数验证器

ThinkPHP实现一个复杂的参数验证器

作者: 红烧排骨饭 | 来源:发表于2018-05-11 15:04 被阅读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();  // 验证参数
        
        // ...
    }
}

相关文章

网友评论

      本文标题:ThinkPHP实现一个复杂的参数验证器

      本文链接:https://www.haomeiwen.com/subject/mtmfdftx.html