需求描述:搭建一個可繼承、可拓展的基類控制,包括:接口加密驗算、身份校驗、參數校驗、請求來源校驗、重寫錯誤處理機制等
功能描述:
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',