異常處理
和PHP默認(rèn)的異常處理不同,ThinkPHP拋出的不是單純的錯(cuò)誤信息,而是一個(gè)人性化的錯(cuò)誤頁面。
默認(rèn)異常處理
在調(diào)試模式下,系統(tǒng)默認(rèn)展示的錯(cuò)誤頁面:
只有在調(diào)試模式下面才能顯示具體的錯(cuò)誤信息,如果在部署模式下面,你可能看到的是一個(gè)簡(jiǎn)單的提示文字,例如:
本著嚴(yán)謹(jǐn)?shù)脑瓌t,5.0版本默認(rèn)情況下會(huì)對(duì)任何錯(cuò)誤(包括警告錯(cuò)誤)拋出異常,如果不希望如此嚴(yán)謹(jǐn)?shù)膾伋霎惓?,可以在?yīng)用公共函數(shù)文件中或者配置文件中使用
error_reporting
方法設(shè)置錯(cuò)誤報(bào)錯(cuò)級(jí)別(請(qǐng)注意,在入口文件中設(shè)置是無效的),例如:
// 異常錯(cuò)誤報(bào)錯(cuò)級(jí)別,
error_reporting(E_ERROR | E_PARSE );
異常處理接管
框架支持異常頁面由開發(fā)者自定義類進(jìn)行處理,需要配置參數(shù)exception_handle
// 異常處理handle類 留空使用 \think\exception\Handle
'exception_handle' => '\\app\\common\\exception\\Http',
自定義類需要繼承Handle
并且實(shí)現(xiàn)render
方法,可以參考如下代碼:
<?php
namespace app\common\exception;
use Exception;
use think\exception\Handle;
use think\exception\HttpException;
class Http extends Handle
{
public function render(Exception $e)
{
// 參數(shù)驗(yàn)證錯(cuò)誤
if ($e instanceof ValidateException) {
return json($e->getError(), 422);
}
// 請(qǐng)求異常
if ($e instanceof HttpException && request()->isAjax()) {
return response($e->getMessage(), $e->getStatusCode());
}
//TODO::開發(fā)者對(duì)異常的操作
//可以在此交由系統(tǒng)處理
return parent::render($e);
}
}
需要注意的是,如果配置了'exception_handle',且沒有再次調(diào)用系統(tǒng)
render
的情況下,配置http_exception_template
就不再生效,具體可以參考Handle
類內(nèi)實(shí)現(xiàn)的功能。
V5.0.11
版本開始,可以通過閉包定義的方式簡(jiǎn)化異常自定義處理,例如,上面的自定義異常類可以改為直接配置exception_handle
參數(shù):
'exception_handle' => function(Exception $e){
// 參數(shù)驗(yàn)證錯(cuò)誤
if ($e instanceof \think\exception\ValidateException) {
return json($e->getError(), 422);
}
// 請(qǐng)求異常
if ($e instanceof \think\exception\HttpException && request()->isAjax()) {
return response($e->getMessage(), $e->getStatusCode());
}
}
部署模式異常
一旦關(guān)閉調(diào)試模式,發(fā)生錯(cuò)誤后不會(huì)提示具體的錯(cuò)誤信息,如果你仍然希望看到具體的錯(cuò)誤信息,那么可以如下設(shè)置:
// 顯示錯(cuò)誤信息
'show_error_msg' => true,
異常捕獲
可以使用PHP的異常捕獲進(jìn)行必要的處理,但需要注意一點(diǎn),在異常捕獲中不要使用think\Controller
類的error、success和redirect方法,因?yàn)樯鲜鋈齻€(gè)方法會(huì)拋出HttpResponseException
異常,從而影響正常的異常捕獲,例如:
try{
Db::name('user')->find();
$this->success('執(zhí)行成功!');
}catch(\Exception $e){
$this->error('執(zhí)行錯(cuò)誤');
}
應(yīng)該改成
try{
Db::name('user')->find();
}catch(\Exception $e){
$this->error('執(zhí)行錯(cuò)誤');
}
$this->success('執(zhí)行成功!');