Thinkphp5進階——01 異常
前言
和PHP預設的異常處理不同,ThinkPHP丟擲的不是單純的錯誤資訊,而是一個錯誤頁面。
如果是做web開發,給客戶端返回這種錯誤頁面還好;但如果是做API開發的話,返回這個頁面客戶端根本無法處理,所以我們需要對異常進行捕獲處理。
異常分類
使用者行為導致的異常
沒有通過驗證器、沒有查詢到結果。
通常不需要記錄日誌,需要向使用者返回具體資訊。
伺服器自身的異常
程式碼錯誤、呼叫外部介面錯誤。
通常需要記錄日誌,不需要向客戶端返回具體原因。
try-catch
相信對於大部分人而言,try-catch並不陌生。
使用try-catch我們可以在可能發生異常的地方進行異常捕獲,然後對異常進行後續處理,返回給客戶端可以處理的錯誤資訊。
例項
try{
// 可能發生異常的業務邏輯
}
catch(Exception $ex){
// RESTful風格的錯誤返回資訊
$err = [
'error_code'=>10001,
'msg'=>$ex->getMessage()
];
// 返回json格式的錯誤資訊,並且規定HTTP狀態碼
return json($err,400);
}
try-catch這種異常捕獲方式存在以下問題:
-
逐層丟擲,如果是最底下的業務邏輯出現了問題會將異常逐層丟擲,否則就會直接被原有的預設異常捕獲到輸出一個預設的錯誤頁面;
-
如果是不可預知的異常,未做try-catch處理的業務邏輯,就會輸出一個預設的錯誤頁面;
-
某些錯誤資訊不適合直接返回給客戶端,需要做統一處理。
總結起來就是繁瑣,不夠健壯。
構建Validate層
實現步驟大致為:
-
自定義錯誤處理器——ExceptionHandler。
-
config.php的exception_hadle配置項修改為上面的自定義錯誤處理器。
-
建立基礎異常處理類——BaseException。
-
建立具體異常處理類——xxxException。
錯誤處理器——ExceptionHandler
1)模組同級目錄下,建立lib/exception資料夾
2)建立ExceptionHandler,繼承think\exception\Handle
3)引用Exception類
4)重寫render方法
我們定義,凡是繼承了BaseException的異常,就屬於使用者導致的異常。
namespace app\lib\exception;
// 引用框架的Exception
use Exception;
// 引用Log類
use think\facade\Log;
// 引用Request類
use think\facade\Request;
// 引用框架的Handle
use think\exception\Handle;
class ExceptionHandler extends Handle
{
private $code;
private $msg;
private $errorCode;
// 重寫框架的render方法
public function render(Exception $e){
// 如果是使用者類錯誤
if($e instanceof BaseException){
$this->code = $e->code;
$this->msg = $e->msg;
$this->errorCode = $e->errorCode;
}
// 如果是伺服器內部錯誤
else{
$switch = config('app.app_debug');
// 開發模式下顯示html頁面
if($switch){
return parent::render($e);
}
// 生產模式下顯示json資料
else{
$this->code = 500;
$this->msg = '伺服器內部錯誤,不想告訴你';
$this->errorCode = 999;
// 寫入日誌
$this->recordErrorLog($e);
}
}
// 返回陣列
$result = [
'msg' => $this->msg,
'errorCode' => $this->errorCode,
'request_url' => Request::url()
];
return json($result,$this->code);
}
// 伺服器內部錯誤資訊寫入日誌
private function recordErrorLog(Exception $e){
Log::write($e->getMessage(),'error');
}
}
基礎異常處理類——BaseException
1)引用Exception類。
2)定義通用異常錯誤的屬性(http狀態碼、錯誤資訊、自定義錯誤碼)。
3)建構函式可以傳值,覆蓋預設屬性。
namespace app\lib\exception;
use Exception;
class BaseException extends Exception
{
// 預設HTTP狀態碼
public $code = 400;
// 預設錯誤提示資訊
public $msg = '引數錯誤';
// 預設業務錯誤碼
public $errorCode = 10000;
// 建構函式
public function __construct($params = [])
{
// 判斷是否陣列
if(!is_array($params)){
return;
}
// 判斷是否有code、errorCode、msg這些引數代入
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'];
}
}
}
具體異常處理類
1)新建對應異常類,繼承BaseException。
2)定義具體的異常錯誤屬性。
namespace app\lib\exception;
class BannerMissException extends BaseException
{
// HTTP狀態碼
public $code = 404;
// 提示錯誤資訊
public $msg = '請求的banner不存在';
// 自定義錯誤碼
public $errorCode = 40000;
}
相關文章
- Java 異常進階Java
- Java進階02 異常處理Java
- Python進階08 異常處理Python
- python進階(7)--檔案與異常Python
- Android進階;App的異常崩潰處理AndroidAPP
- Python 快速教程(進階篇08):異常處理Python
- jmu-Java-06異常-01-常見異常Java
- day_19 JavaSE高階_異常Java
- Spring進階之@ControllerAdvice與統一異常處理SpringController
- 異常篇——異常處理
- 異常和異常呼叫鏈
- Oracle:異常ORA-01950Oracle
- ThinkPHP5 使用 JWT 進行加密PHPJWT加密
- Java 異常(二) 自定義異常Java
- Java checked異常和unchecked異常。Java
- 異常總結2013-03
- 異常-編譯期異常和執行期異常的區別編譯
- 異常-throws的方式處理異常
- 異常處理與異常函式函式
- Java面試題中高階進階(JVM篇01)Java面試題JVM
- CSS進階09-定位體系差異分析CSS
- Java常見面試真題之中級進階Java面試
- Java進階01 String類Java
- Python進階01 詞典Python
- hibernate異常之--count查詢異常
- Java 異常表與異常處理原理Java
- restframework 異常處理及自定義異常RESTFramework
- oracle 異常Oracle
- OutOfMemoryError異常Error
- Java異常Java
- 異常(Exception)Exception
- Java 異常Java
- 異常JavaJava
- 【java】異常Java
- java 異常Java
- javamail 配置多個郵箱進行傳送 異常JavaAI
- Flutter 常見異常分析Flutter
- 初階技能:Android 應用異常如何豐富線索Android