关于探讨 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
验证器 正常写规则 但不过一定要加 场景规则 就可以了
不错的思路。
因为比较懒 沿用了之前tp想出来的思路
我也是中间件自己实现了 tp的表单验证器 好用
懒人福音 很good
只需要3步……也不需要考虑性能……
第1步,验证器声明验证失败抛出异常,如:
第2步,控制器引用并验证,如:
第3步,异常处理类接住验证器抛出的异常,如: