【懒人福音】基于 think-validate 实现自动验证器

mto

关于探讨 think-validate 验证器

前因

自己比较懒 不想一直使用创建类的方法 以及手动使用规则验证 所以写了一个中间件来按照格式自动调用验证器 而且之前也使用过thinkphp的验证器 感觉用起来比较舒服

中间件代码

下面直接放代码 有需要的同学可以自行调用【没测试过是否会影响性能,只是感觉用起来比较舒服,感兴趣的小伙伴可以自行测试】

<?php

namespace app\middleware;

use think\exception\ValidateException;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;

class ParamValidate implements MiddlewareInterface
{

    public function process(Request $request, callable $handler) : Response
    {
        $params = $request->all();
        $controller = $request->controller;
        $action = $request->action;
        $method = $request->method();
        $scene = strtolower( "{$method}_{$action}");

        //获取验证器类
        $validate = str_replace('controller','validate',$controller);
        $validate = str_replace('Controller','',$validate);

        //验证器如果不存在 则跳过验证
        if (!class_exists($validate)){
            return $handler($request);
        }

        //调用验证器
        $validate_object = new $validate;
        $val_scene_datas = data_get($validate_object,'scene',[]);
        $val_scene_keys = array_keys($val_scene_datas);

        //没有验证场景则跳过验证
        if (!in_array($scene,$val_scene_keys)){
            return $handler($request);
        }

        try {
            //验证场景
            if (!$validate_object->scene($scene)->check($params)) {
                throw new ValidateException($validate_object->getError());
            }
        }catch (ValidateException $e){
            //错误返回格式可以自定义
            return json(['code'=>0,'msg'=>$e->getError()]);
        }

        return $handler($request);
    }

}

实现思路

1.获取到请求方法所在控制器的路径

$controller = $request->controller;

2.然后按照格式替换一下格式 这里我把验证器规则 放在了跟控制器同目录下的validate目录下 并将Controller直接去掉 例如你的验证器是 AuthController 你的验证规则直接创建为类名 Auth 就可以了

$validate = str_replace('controller','validate',$controller);
$validate = str_replace('Controller','',$validate);

3.获取到调用的方法名和请求方法 组合一下 组成 请求方法_方法名 的格式 方便后面使用

验证器实例规则

附加一个验证器实例规则代码

<?php

namespace app\api\validate;

use think\Validate;

class Auth extends Validate
{
    /**
     * 定义验证规则
     * 格式:'字段名' =>  ['规则1','规则2'...]
     *
     * @var array
     */
    protected $rule = [
        'id' => 'require|integer',
        'title'  => 'require|max:255|min:1'
    ];

    /**
     * 定义错误信息
     * 格式:'字段名.规则名' =>  '错误信息'
     *
     * @var array
     */
    protected $message = [
        'id.require' => 'id不能为空',
        'id.integer' => 'id必须为整数',
        'title.require' => '标题不能为空',
        'title.max'     => '标题最多不能超过255个字符',
        'title.min'     => '标题最少不能少于1个字符',
    ];

    public $scene = [
        'post_register'  =>  ['id','title'],
    ];

}

最后看情况引入全局中间件或者再路由器分组引入 就会自动根据场景 自动调用验证器规则了

样例

例如 你的控制器所在
app/api/controller/AuthController
那你只需要创建
app/api/validate/Auth

验证器 正常写规则 但不过一定要加 场景规则 就可以了

109 3 1
3个评论

efnic

不错的思路。

  • mto 1天前

    因为比较懒 沿用了之前tp想出来的思路

tanhongbin

我也是中间件自己实现了 tp的表单验证器 好用

oliusha

只需要3步……也不需要考虑性能……

第1步,验证器声明验证失败抛出异常,如:

// 验证失败 抛出异常
protected bool $failException = true;

第2步,控制器引用并验证,如:

$params = $request->all();
$this->validate->check($params);

第3步,异常处理类接住验证器抛出的异常,如:

if ($e instanceof ValidateException) {
... some code
}
  • 暂无评论

mto

200
积分
0
获赞数
0
粉丝数
5天前 加入
×
🔝