關(guān)于探討 think-validate 驗(yàn)證器
自己比較懶 不想一直使用創(chuàng)建類的方法 以及手動(dòng)使用規(guī)則驗(yàn)證 所以寫了一個(gè)中間件來(lái)按照格式自動(dòng)調(diào)用驗(yàn)證器 而且之前也使用過(guò)thinkphp的驗(yàn)證器 感覺用起來(lái)比較舒服
下面直接放代碼 有需要的同學(xué)可以自行調(diào)用【沒測(cè)試過(guò)是否會(huì)影響性能,只是感覺用起來(lái)比較舒服,感興趣的小伙伴可以自行測(cè)試】
<?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}");
//獲取驗(yàn)證器類
$validate = str_replace('controller','validate',$controller);
$validate = str_replace('Controller','',$validate);
//驗(yàn)證器如果不存在 則跳過(guò)驗(yàn)證
if (!class_exists($validate)){
return $handler($request);
}
//調(diào)用驗(yàn)證器
$validate_object = new $validate;
$val_scene_datas = data_get($validate_object,'scene',[]);
$val_scene_keys = array_keys($val_scene_datas);
//沒有驗(yàn)證場(chǎng)景則跳過(guò)驗(yàn)證
if (!in_array($scene,$val_scene_keys)){
return $handler($request);
}
try {
//驗(yàn)證場(chǎng)景
if (!$validate_object->scene($scene)->check($params)) {
throw new ValidateException($validate_object->getError());
}
}catch (ValidateException $e){
//錯(cuò)誤返回格式可以自定義
return json(['code'=>0,'msg'=>$e->getError()]);
}
return $handler($request);
}
}
1.獲取到請(qǐng)求方法所在控制器的路徑
$controller = $request->controller;
2.然后按照格式替換一下格式 這里我把驗(yàn)證器規(guī)則 放在了跟控制器同目錄下的validate目錄下 并將Controller直接去掉 例如你的驗(yàn)證器是 AuthController 你的驗(yàn)證規(guī)則直接創(chuàng)建為類名 Auth 就可以了
$validate = str_replace('controller','validate',$controller);
$validate = str_replace('Controller','',$validate);
3.獲取到調(diào)用的方法名和請(qǐng)求方法 組合一下 組成 請(qǐng)求方法_方法名 的格式 方便后面使用
附加一個(gè)驗(yàn)證器實(shí)例規(guī)則代碼
<?php
namespace app\api\validate;
use think\Validate;
class Auth extends Validate
{
/**
* 定義驗(yàn)證規(guī)則
* 格式:'字段名' => ['規(guī)則1','規(guī)則2'...]
*
* @var array
*/
protected $rule = [
'id' => 'require|integer',
'title' => 'require|max:255|min:1'
];
/**
* 定義錯(cuò)誤信息
* 格式:'字段名.規(guī)則名' => '錯(cuò)誤信息'
*
* @var array
*/
protected $message = [
'id.require' => 'id不能為空',
'id.integer' => 'id必須為整數(shù)',
'title.require' => '標(biāo)題不能為空',
'title.max' => '標(biāo)題最多不能超過(guò)255個(gè)字符',
'title.min' => '標(biāo)題最少不能少于1個(gè)字符',
];
public $scene = [
'post_register' => ['id','title'],
];
}
最后看情況引入全局中間件或者再路由器分組引入 就會(huì)自動(dòng)根據(jù)場(chǎng)景 自動(dòng)調(diào)用驗(yàn)證器規(guī)則了
例如 你的控制器所在
app/api/controller/AuthController
那你只需要?jiǎng)?chuàng)建
app/api/validate/Auth
驗(yàn)證器 正常寫規(guī)則 但不過(guò)一定要加 場(chǎng)景規(guī)則 就可以了
只需要3步……也不需要考慮性能……
第1步,驗(yàn)證器聲明驗(yàn)證失敗拋出異常,如:
// 驗(yàn)證失敗 拋出異常
protected bool $failException = true;
第2步,控制器引用并驗(yàn)證,如:
$params = $request->all();
$this->validate->check($params);
第3步,異常處理類接住驗(yàn)證器拋出的異常,如:
if ($e instanceof ValidateException) {
... some code
}
不錯(cuò)的思路。