# 錯誤處理規范
## 為什么使用Exception方式
為了加深印象,特別舉例以供參考
目前PHPer開發人員有幾種習慣去返回錯誤,常見如下:
### return False|NULL
~~~
if(!$mysql->real_connect('xxx','xxx')){
return FALSE;
}
~~~
缺點:業務使用時,需要對返回值進行===FALSE進行判斷。錯誤原因較難獲取,只能通過查看error\_log或打斷點獲取故障原因,而返回結果和錯誤標志較難區分,使用時容易出誤會,同時常見配合此類方式的還會使用gloabl變量保存錯誤原因及code。不能知道具體哪里或業務邏輯報錯。
### return array('code'=>-123,'msg'=>'reason')
~~~
if(!$mysql->real_connect('xxx','xxx')){
return array('code'=> $mysql->getErrorNumber(),'msg'=> $mysql->getMsg());
}
~~~
缺點:維護較復雜,如果代碼層級深,需要將錯誤信息一層層傳遞到頂層controller或service內方可展示給用戶(因為接口輸出結果格式由controller和service層決定)并且無法第一時間得知是哪個文件拋出的故障。
### throw new Exception()
~~~
if(!$mysql->real_connect('xxx','xxx')){
throw new Exception('code'=> $mysql->getErrorNumber(),'msg'=> $mysql->getMsg());
}
~~~
缺點:比較暴力的方式,所有地方需要try catch才能保證頁面不會因為exception白屏,500。但是暴露問題很方便,故障可以很快通過backtrace獲取到事發地點。
推薦使用throw Exception方式,方便簡單,不用一級級傳遞,能夠快速定位到錯誤點。至于Exception及500錯誤可以使用set exception handle進行最后一步攔截并記錄錯誤日志即可
注意:除非業務需要盡量不要在代碼內實現try cache攔截異常,否則會導致底層異常被攔截不易追蹤
* * *
## 框架異常處理措施
目前框架在fend/fend.php中定義了register\_shutdown\_function
此函數在項目推出時會自動觸發函數對最后一次錯誤信息(使用error\_get\_last()函數,命令行也可工作)對錯誤信息進行收集整理,若當前請求在fpm的debug模式下,會在請求結尾輸出具體debug信息到返回值