什么是異常
從更加廣泛的角度來看,異常包含兩個方面,一方面是程序執(zhí)行時由于語法、運行時錯誤等導(dǎo)致的異常,一方面時沒有給予正確的反饋,如客戶端要查詢某個產(chǎn)品,沒有查詢到,我認(rèn)為這也屬于異常的一種。
第一種異常TP框架本身會在頁面中輸出錯誤信息,但是第二種異常則一般不會輸出任何信息,所以非常不方便調(diào)試。
本文將詳細(xì)介紹關(guān)于ThinkPHP異常處理的相關(guān)內(nèi)容,分享出來供大家參考學(xué)習(xí),下面話不多說了,來一起看看詳細(xì)的介紹吧。
前提環(huán)境
現(xiàn)在 PHP 在很多時候是為前端提供接口,所以我們的異常處理也基于這一點進(jìn)行處理。
在開發(fā)階段,TP 原有的異常處理是在頁面中輸出異常信息,這一點能夠滿足需求,但在生產(chǎn)環(huán)境中,則需要以其他方式處理異常。
本文都是針對生產(chǎn)環(huán)境的異常處理
AOP 編程
現(xiàn)在在很多語言中,都非常流行 AOP 編程思想,即面向切面編程思想,通俗的說,就是用統(tǒng)一的方式處理問題,而不是用相同的方式分別處理多個問題,對于異常處理來說,就是定義統(tǒng)一的異常信息,用統(tǒng)一的方式處理
大致思路
自定義異常處理類,重寫默認(rèn)異常處理類的 render 方法,然后配置使用自定義異常處理類處理所有異常
代碼實現(xiàn)
在根目錄下創(chuàng)建目錄 exception,在其下創(chuàng)建ExceptionHandle.php,此類要繼承 handle 類
class ExceptionHandler extends Handle
創(chuàng)建幾個屬性,用于定義異常信息
// http 錯誤碼
private $code;
// 自定義異常信息
private $msg;
// 自定義錯誤碼
private $errorCode;
覆蓋 Handle 類中的render 方法,當(dāng)我們在代碼中使用 throw new Exception() 方式拋出異常信息時,其實就是調(diào)用了 render 方法,所以我們要重寫此方法,以返回我們自己的信息
public function render(Exception $ex)
{
return json(['msg'=>"自定義異常信息"]);
nbsp; }
下面新建控制器 Product,添加方法,進(jìn)行測試
public function getProduct($id)
{
try{
3/0;
}
catch(Exception $ex){
throw $ex;
}
}
然后添加如下路由
Route::get("product/:id","api/v1.Product/getProduct");
輸入如下url 測試
http://z.cn/product/2
頁面輸出結(jié)果如下
可見,其并沒有執(zhí)行自定義異常處理函數(shù)。
使用自定義的異常處理
在 config.php 中修改如下配置
// 異常處理handle類 留空使用 \think\exception\Handle
'exception_handle' => 'app\lib\exception\ExceptionHandler',
然后再運行
自定義異常處理類
一類異常是用戶行為導(dǎo)致的異常,比如沒有查詢到符合條件的數(shù)據(jù)(從另一個角度來說,這其實不算異常),一類錯誤是運行時錯誤。而用戶導(dǎo)致的異??赡芊譃楹芏喾N,所以需要自定義相關(guān)的類。
首先定義一個父類
class BaseException extends Exception
{
//http 狀態(tài)碼
public $code;
//錯誤具體消息
public $msg;
//自定義錯誤碼
public $errorCode;
//構(gòu)造函數(shù)用于接收傳入的異常信息,并初始化類中的屬性
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'];
}
}
}
再定義一個處理找不到產(chǎn)品信息的異常處理類,用來重寫父類中的各個屬性,而且這個類中的屬性信息也可能會被修改,如 msg
class ProductNotFoundException extends BaseException
{
//http 狀態(tài)碼
public $code = 404;
//錯誤具體消息
public $msg = "請求的產(chǎn)品不存在";
//自定義錯誤碼
public $errorCode = 40000;
}
處理不同異常
在 render 方法中,根據(jù)異常的不同分別處理
//分別處理兩種不容類型異常:1、用戶錯誤 2.代碼與運行時錯誤
if ($ex instanceof BaseException) {
} else {
}
說明:在 throw 異常時,會執(zhí)行 render 函數(shù),同時會將拋出的異常對象復(fù)制給參數(shù) $ex,所以可以根據(jù)此參數(shù)判斷異常類型
現(xiàn)在的關(guān)鍵是生產(chǎn)環(huán)境,所以希望返回的異常信息,前端人員能夠看懂,而不是像上面那樣在頁面中輸出錯誤信息,還包括堆棧信息等。
那么前前端賀后端人員都能夠看懂的信息一定是 json(當(dāng)然也可以是xml)了,修改 render 方法
if ($ex instanceof BaseException) {
$this->code = $ex->code;
$this->msg = $ex->msg;
$this->errorCode = $ex->errorCode;
} else {
//這里是在運行時產(chǎn)生的各種異常,所以無法準(zhǔn)確輸出異常信息,所以只能統(tǒng)一輸出是服務(wù)器錯誤信息
$this->code = 500;
$this->msg = "服務(wù)器內(nèi)部錯誤";
$this->errorCode = 999;
}
然后以 json 格式返回錯誤信息
$result = [
'msg' => $this->msg,
'error_code' => $this->errorCode,
'request_url' => request()->url()
];
return json($result,$this->code);
至此,全局的異常處理就編寫好了,下面在 product.php 中編碼進(jìn)行測試
public function getProduct($id)
{
//處理程序運行時錯誤
/*try{
3/0;
}
catch(Exception $ex){
throw $ex;
}*/
//處理用戶行為產(chǎn)生的錯誤
$error=[
'msg'=>'沒有找到合適的產(chǎn)品'
];
$ex=new ProductNotFoundException($error);
throw $ex;
}
提示:生產(chǎn)環(huán)境不要忘了將 app_debug 修改為 false
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
您可能感興趣的文章:- 讓whoops幫我們告別ThinkPHP6的異常頁面
- Thinkphp 在api開發(fā)中異常返回依然是html的解決方式
- 解決thinkphp5未定義變量會拋出異常,頁面錯誤,請稍后再試的問題
- thinkPHP線上自動加載異常與修復(fù)方法實例分析
- ThinkPHP中自定義錯誤頁面和提示頁面實例
- TP5(thinkPHP5框架)實現(xiàn)顯示錯誤信息及行號功能的方法
- ThinkPHP下表單令牌錯誤與解決方法分析
- ThinkPHP表單令牌錯誤的相關(guān)解決方法分析
- thinkPHP自動驗證、自動添加及表單錯誤問題分析
- ThinkPHP3.2.3框架實現(xiàn)的空模塊、空控制器、空操作,跳轉(zhuǎn)到錯誤404頁面圖文詳解
- Thinkphp5框架異常處理操作實例分析