## 傳統變量驗證方式
我們之前在做開發時候,在進行變量驗證時,往往是控制器或者邏輯層在用之前驗證。這種方式時間長了,有可能會出現忘記驗證的情況。本文介紹如何利用前置中間件自動完成變量驗證。
前置中間件官方手冊:[中間件 - ThinkPHP5.1完全開發手冊](http://www.hmoore.net/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的對應關系。