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