需求描述:搭建一个可继承、可拓展的基类控制,包括:接口加密验算、身份校验、参数校验、请求来源校验、重写错误处理机制等
功能描述:
1.api接口类继承基类,相关校验处理机制,由基类完成
2.自定义错误处理机制,包括:程序异常、自定义异常、错误日志收集
基类(Base)
namespace app\common\controller;
use think\Controller;
use think\Response;
use \app\common\controller\lib\BaseException;
class Base extends Controller{
public $httpCode = 200;
public $code;
public $message;
public $data = [];
public function _initialize(){
parent::_initialize(); // TODO: Change the autogenerated stub
$url = strtolower($this->request->module() . '/' . $this->request->controller() .'/' . $this->request->action());
$header = $this->request->header();
$param = $this->request->param();
/**
* 校验处理(可自主拓展)。。。
*/
//秘钥校验
$is_checkkey = $this->checkGetKey();
if($is_checkkey === false){
$this->httpCode = 401;
$this->code = 401;
$this->message = '身份校验失败';
goto error;
}
return true;
error:{
$this->returnText();
}
}
/**
* 空操作
* @param $name
* @return mixed
*/
public function _empty($name){
$message = '请求异常#' . $name;
$this->returnText(404,$message,[],404);
}
/**
* 客户端数据返回
* @param null $code
* @param null $message
* @param array $data
* @param null $httpCode
*/
public function returnText($code = null,$message = null,$data = [],$httpCode = null){
$array = [
'code' => empty($code) ? $this->code : $code,
'message' => empty($message) ? $this->message : $message,
'data' => $data ? $data : $this->data
];
Response::create($array,'json',empty($httpCode) ? $this->httpCode : $httpCode,[],[])->send();
exit();
}
/**
* 自定义程序异常处理返回
* @param null $code
* @param null $message
* @param array $data
* @param null $httpCode
* @throws BaseException
*/
public function exception($code = null,$message = null,$data = [],$httpCode = null){
$array = [
'code' => empty($code) ? $this->code : $code,
'message' => empty($message) ? $this->message : $message,
'data' => $data ? $data : $this->data,
'errorCode' => empty($httpCode) ? $this->httpCode : $httpCode,
];
throw new \app\common\controller\lib\BaseException($array);
}
/**
* 校验当前接口链接是否需要秘钥校验
* @param string $url
* @return bool
*/
public function ignoreAction($url){
}
/**
* 判断秘钥是否有效
* 必须同时匹配成功
* @param string $appID
* @param string $apiKey
* @return array|bool
*/
public function checkGetKey($appID,$apiKey){
}
/**
* 校验身份认证
* @param string $appID
* @param string $time
* @param string $token
* @return bool
*/
public function checkToken($appID, $time, $token){
}
/**
* 校验sign是否合法
* @param array $data
* @return bool
*/
public function checkSign($data){
}
/**
* 传参键名排序,加密获取sign
* @param array $data
* @param string $method
* @return string
*/
public function getSignature($data,$method = 'md5'){
}
/**
* 校验用户身份,以及状态
* @return bool
*/
/**
* 校验请求来源
* @return bool
*/
/**
* 校验请求来源
* @return bool
*/
}
调用示例类(Index)
namespace app\index\controller;
use app\common\controller\Base;
class Index extends Base {
public function _initialize(){
return parent::_initialize(); // TODO: Change the autogenerated stub
}
public function index(){
$data = $this->request->param();
$this->data = $data;
$this->code = 200;
$this->message = '查看';
$this->returnText(200,'查看',$data,200); //调用接口正常返回
echo $a; //调用程序异常返回
$this->exception(404,'server error',[],404); //调用自定义异常返回
}
}
框架错误类重写(ExceptionHandle)
namespace app\common\controller\lib;
use \think\exception\Handle;
use Exception;
class ExceptionHandle extends Handle{
private $code;
private $msg;
private $errorCode;
private $status;
private $data;
public function render(Exception $e)
{
if ($e instanceof BaseException) {
//如果是自定义异常,则控制http状态码,不需要记录日志
//因为这些通常是因为客户端传递参数错误或者是用户请求造成的异常
$this->code = $e->code;
$this->msg = $e->msg;
$this->errorCode = $e->errorCode;
$this->status = $e->status;
$this->data = $e->data;
} else{
// 如果是服务器未处理的异常,将http状态码设置为500,并记录日志
if(config('APP_DEBUG')){
// 调试状态下需要显示TP默认的异常页面,因为TP的默认页面
// 很容易看出问题
return parent::render($e);
}
$this->code = '500';
$this->msg = 'server error';
$this->errorCode = 999;
$this->status = 0;
$this->data = (object)[];
//日志记录
$this->recordErrorLog($e);
}
$result = [
'code' => $this->code,
'data' => $this->data,
'msg' => $this->msg,
];
return json($result, $this->code);
}
/*
* 将异常写入日志
*/
private function recordErrorLog(Exception $e){
}
自定义错误类(BaseException)
namespace app\common\controller\lib;
use think\Exception;
class BaseException extends Exception{
public $code = '400';
public $msg = 'invalid parameters';
public $errorCode = 999;
public $status = 0;
public $data = '';
public $shouldToClient = true;
/**
* 构造函数,接收一个关联数组
* @param array $params 关联数组只应包含code、msg和errorCode,且不应该是空值
*/
public function __construct($params=[])
{
$this->data = (object)[];
if(!is_array($params)){
return;
}
if(array_key_exists('code',$params)){
$this->code = $params['code'];
}
if(array_key_exists('message',$params)){
$this->msg = $params['message'];
}
if(array_key_exists('errorCode',$params)){
$this->errorCode = $params['errorCode'];
}
if(array_key_exists('data',$params)){
$this->data = $params['data'];
}
}
}
设置config.php文件(否则错误处理类无法生效)
//开发时,开启debug
'app_debug' => true,
// 异常处理handle类 留空使用 \think\exception\Handle
'exception_handle' => '\app\common\controller\lib\ExceptionHandle',