## 传统变量验证方式
我们之前在做开发时候,在进行变量验证时,往往是控制器或者逻辑层在用之前验证。这种方式时间长了,有可能会出现忘记验证的情况。本文介绍如何利用前置中间件自动完成变量验证。
前置中间件官方手册:[中间件 - ThinkPHP5.1完全开发手册](https://ihavenolimitations.xyz/manual/thinkphp5_1/564279)
## 1、创建`app\common\lib\Validate`类
```
namespace app\common\lib;
use app\common\exception\CommonException;
use think\facade\Request;
class Validate
{
public function __construct()
{
$this->validateParam();
}
/**根据控制器和方法验证输入变量
* @return bool
* @throws CommonException
*/
protected function validateParam()
{
$class = 'app\\'.Request::module().'\validate\\'.Request::controller();
if(class_exists($class)&&app($class)->hasScene(strtolower(Request::action()))){
if(app($class)->scene(Request::action())->check(Request::param())){
return true;
}else{
throw new CommonException('-1',app($class)->getError());
}
}else{
return true;
}
}
}
```
解释一下执行逻辑:假如客户端请求的URL是`www.domain.com/index.php/index/User/login/`时,如果存在`app\index\validate\User`的验证类,且验证类中有`login`的验证场景时,程序会自动完成变量验证工作,如果没有通过验证,则抛出异常。
## 2、在前置中间件中使用容器管理快速调用自动验证类
```
namespace app\http\middleware;
class Before
{
public function handle($request, \Closure $next)
{
app('app\common\lib\Validate');
return $next($request);
}
}
```
## 3、创建验证类
```
namespace app\index\validate;
use think\Validate;
class User extends Validate
{
protected $rule = [
'phone' => 'require|mobile',
'vercode' => 'require|number|length:6',
'password' => 'require|alphaNum|length:8,20',
'repassword' => 'require|confirm:password'
];
protected $message = [
'phone.require' => '未填写手机号码',
'phone.mobile' => '手机号码格式错误,请填写11位手机号码',
'vercode.require' => '请填写验证码',
'vercode.number' => '验证码错误,验证码为6位数字',
'vercode.length' => '验证码格式错误,验证码为6位数字',
'password.require' => '请填写密码(字母或数字)',
'password.alphaNum' => '密码格式错误,密码为字母或数字',
'password.length' => '密码长度错误,密码为8-20位字母或数字组合',
'repassword.require' => '请在确认密码处再次输入密码',
'repassword.confirm' => '两次密码不一致,请确认'
];
protected $scene = [
'login' => ['phone','password']
'reg' => ['phone','password','vercode','repassword']
];
}
```
注意一点,**场景名不区分大小写,且在调用的时候不能将驼峰写法转为下划线**。所以注意验证场景和action的对应关系。