ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] ## **验证器进阶** ### **app\api\controller\v1\Banner.php** ``` namespace app\api\controller\v1; use app\api\controller\BaseController; use app\api\validate\IDMustBePositiveInt; use app\api\model\Banner as BannerModel; use app\lib\exception\MissException; class Banner extends BaseController { /** * 获取Banner信息 * @url /banner/:id * @http get * @param int $id banner id * @return array of banner item , code 200 * @throws MissException */ public function getBanner($id) { $validate = new IDMustBePositiveInt(); $validate->goCheck(); $banner = BannerModel::getBannerById($id); if (!$banner ) { throw new MissException([ 'msg' => '请求banner不存在', 'errorCode' => 40000 ]); } return $banner; } } ``` ## **app\api\validate\IDMustBePositiveInt.php** ``` namespace app\api\validate; class IDMustBePositiveInt extends BaseValidate { protected $rule = [ 'id' => 'require|isPositiveInteger', ]; } ``` ## **app\api\validate\BaseValidate.php** ``` namespace app\api\validate; use app\lib\exception\ParameterException; use think\Request; use think\Validate; /** * Class BaseValidate * 验证类的基类 */ class BaseValidate extends Validate { /** * 检测所有客户端发来的参数是否符合验证类规则 * 基类定义了很多自定义验证方法 * 这些自定义验证方法其实,也可以直接调用 * @throws ParameterException * @return true */ public function goCheck() { //必须设置contetn-type:application/json $request = Request::instance(); $params = $request->param(); $params['token'] = $request->header('token'); if (!$this->check($params)) { $exception = new ParameterException( [ // $this->error有一个问题,并不是一定返回数组,需要判断 'msg' => is_array($this->error) ? implode( ';', $this->error) : $this->error, ]); throw $exception;//此处为自定义错误处理类,完整请参看【验证进阶之最终版】或者【错误和日志---异常处理】 } return true; } protected function isPositiveInteger($value, $rule='', $data='', $field='') { if (is_numeric($value) && is_int($value + 0) && ($value + 0) > 0) { return true; } return $field . '必须是正整数'; } } ``` ## **错误处理相关代码** 在`app`目录下面的`provider.php`文件中绑定异常处理类,例如: 替换原有的vendor\\topthink\\framework\\src\\think\\exception\\Handle.php的Handle类 ~~~ // 绑定自定义异常处理handle类 'think\exception\Handle' => '\\app\\common\\exception\\Http', 'exception_handle' => '\app\lib\exception\ExceptionHandler',//这是tp5的config.php的配置 ~~~ >[danger] 事实上,默认安装应用后,已经帮你内置了一个公共的`app\ExceptionHandle`异常处理类(作用于index、admin、api等所有模块)它继承至默认的handle类,直接修改该类的相关方法即可完成应用的自定义异常处理机制。而无需在自定义Handle类 ### **app\lib\exception\ExceptionHandler.php** ``` <?php namespace app\lib\exception; use think\exception\Handle; use think\Log; use think\Request; use Exception; /* * 重写Handle的render方法,实现自定义异常消息 */ class ExceptionHandler extends Handle { private $code; private $msg; private $errorCode; public function render(Exception $e) { if ($e instanceof BaseException) { //如果是自定义异常,则控制http状态码,不需要记录日志 //因为这些通常是因为客户端传递参数错误或者是用户请求造成的异常 //不应当记录日志 $this->code = $e->code; $this->msg = $e->msg; $this->errorCode = $e->errorCode; } else{ // 如果是服务器未处理的异常,将http状态码设置为500,并记录日志 if(config('app_debug')){ // 调试状态下需要显示TP默认的异常页面,因为TP的默认页面 // 很容易看出问题 return parent::render($e); } $this->code = 500; $this->msg = 'sorry,we make a mistake. (^o^)Y'; $this->errorCode = 999; $this->recordErrorLog($e); } $request = Request::instance(); $result = [ 'msg' => $this->msg, 'error_code' => $this->errorCode, 'request_url' => $request = $request->url() ]; return json($result, $this->code); } /* * 将异常写入日志 */ private function recordErrorLog(Exception $e) { Log::init([ 'type' => 'File', 'path' => LOG_PATH, 'level' => ['error'] ]); // Log::record($e->getTraceAsString()); Log::record($e->getMessage(),'error'); } } ``` ### **app\lib\exception\BaseException.php** ``` <?php namespace app\lib\exception; use think\Exception; /** * Class BaseException * 自定义异常类的基类 */ class BaseException extends Exception { public $code = 400; public $msg = 'invalid parameters'; public $errorCode = 999; public $shouldToClient = true; /** * 构造函数,接收一个关联数组 * @param array $params 关联数组只应包含code、msg和errorCode,且不应该是空值 */ public function __construct($params=[]) { if(!is_array($params)){ return; } if(array_key_exists('code',$params)){ $this->code = $params['code']; } if(array_key_exists('msg',$params)){ $this->msg = $params['msg']; } if(array_key_exists('errorCode',$params)){ $this->errorCode = $params['errorCode']; } } } ``` ### **app\lib\exception\ParameterException.php** ``` <?php namespace app\lib\exception; /** * Class ParameterException * 通用参数类异常错误 */ class ParameterException extends BaseException { public $code = 400; public $errorCode = 10000; public $msg = "invalid parameters"; } ```