關於PHP自動捕捉處理錯誤和異常的嘗試

2022-03-13 16:22:34 字數 4440 閱讀 3784

之所以想著做錯誤和異常的自動處理是因為:

用的公司自己的框架寫api,沒有異常和錯誤相關功能,

而每次操作都進行try...catch,有點繁瑣不說,感覺還很雞肋,即使我catch到了,還是得寫**進行處理,哪怕封裝了乙個方法進行處理也還是繁瑣,

這種情況應該是程式自動進行處理,不該是這樣弱智的人工try...catch,然後處理

以及其他同事寫**時並不能嚴格的進行try...catch

於是乎,想自己設計乙個自動捕獲並處理錯誤和異常的功能。

發現了一篇深度好文:

理解了php中自帶的register_shutdown_function,set_error_handler,set_exception_handler這三個函式

通過這三個函式我們可以實現php假 自動捕獲異常和錯誤。php5也不支援error的捕獲,只能try...catch (exception) 

三個函式必須理解,如果你想實現該功能,希望你可以先做個小demo體驗下三個函式的神奇之處

這三個函式需要你寫在框架的生命週期比較靠前的地方,如果不知道寫**,請寫在入口檔案中,或者在入口檔案require一下(下面的原始碼可以直接require使用)

因為如果寫到其他檔案中,而碰巧該檔案有錯誤或者異常,那麼這三個函式就不發生作用了,而入口檔案我們都可以確保正確

正文:

首先介紹set_error_handler這個函式,這個函式用於捕獲低階別的錯誤,該函式只能捕獲系統產生的一些warning、notice級別的錯誤,並呼叫乙個使用者自定義的錯誤處理函式。

比如在入口檔案寫入  set_error_handler('low_level_error'),並且我們建立了low_level_error 自定義方法來進行日誌的記錄 。

當發生warning、notice級別的錯誤時,系統會自動呼叫low_level_error方法,四個引數

"type"、 "message"、"file" 和 "line"

也是系統傳過來的,可以直接使用。

注意:使用此函式後  

error_reporting ( e_all )  無法提示warning和notice級別的警告, 如果本地開發,最好關閉此函式,在生產環境才使用;  使用其它兩個函式時錯誤提示資訊不受影響

可以使用下面原始碼中的單個方法進行測試, 只需echo $str; exit;

就好第二個函式register_shutdown_function,這個函式與第乙個函式搭配使用,可以捕捉到fatal error、parse error等高階別會讓程式中止的錯誤,

這個方法是php指令碼執行結束前最後乙個呼叫的函式,比如指令碼錯誤、die()、exit、異常、正常結束都會呼叫。這個方法沒有接受引數,所以需要借助error_get_last(),error_get_last函式可以獲取到

系統最近發生的乙個錯誤,同樣包含  

"type"、 "message"、"file" 和 "line"四個字段,需要注意的是 本函式捕捉到的 (

2,8,32,128,512,1024,2048,8192)等錯誤都是警告級別的,自己酌情處理。

第三個函式set_exception_handler, 這個函式可以捕獲 沒有用try/catch塊來捕獲的異常,並且在**函式呼叫後異常會中止(這個我沒有試,因為我捕捉異常後直接返回給前端錯誤code碼了)。

思路:通過set_error_handlerregister_shutdown_function兩個函式可以捕捉到所有的錯誤,通過set_exception_handler捕捉所有未處理的異常,這樣程式中所有的錯誤和異常就被我們捕捉到了,

接下來,我們可以通過自定義函式對它們進行操作,由於我的業務是直接向前端輸出,因此只是記錄相關日誌後直接echo並退出,大家可以在自定義函式內自己決定做什麼處理。

還可以在兩個自定義的錯誤處理函式中再丟擲異常,由自定義的異常處理類統一處理,這也是乙個不錯的思路,大家可以嘗試下。

最後:

<?php

/**引入本檔案後,php會自動處理錯誤和異常, php版本5.6, php7+版本需要小調整,執行時根據提示調整即可

* 本方法直接捕捉錯誤並記錄日誌,如有興趣,可以捕捉到錯誤後再次丟擲異常,將錯誤轉為異常後,由set_exception_handler統一進行處理

* user: lizheng [email protected]

* date: 2019/3/21 */

register_shutdown_function('high_level_error'); //

使用了register_shutdown_function 後,當程式遇見一些致命錯誤時會自動呼叫函式 high_level_error

set_error_handler('low_level_error'); //

使用了set_error_handler 後,當程式遇見notice 和warning錯誤時會自動呼叫函式 low_level_error

set_exception_handler('exception_log'); //

使用了set_exception_handler後,當遇到所有的未捕獲的異常時會自動呼叫函式 exception_log/**

* 該方法只能捕獲系統產生的一些warning、notice級別的錯誤

* @param $type

* @param $message

* @param $file

* @param $line

* user: lizheng [email protected]

* date: 2019/3/21 */

function low_level_error($type, $message, $file, $line)/*

* * 捕捉一些致命錯誤

* user: lizheng [email protected]

* date: 2019/3/21 */

function

high_level_error()

}else

//直接輸出介面的返回資訊, 給前端乙個錯誤碼code, msg返回時間用於方便查詢日誌

echo json_encode(array('code'=>err_error, 'msg'=>$time, 'data'=>array()), true);exit

; }

}}/*

* * 捕捉異常

* @param $exception

* user: lizheng [email protected]

* date: 2019/3/21 */

function exception_log($exception)/*

* * class error_handler

* create on 2019/3/21 14:15

* user: lizheng [email protected]

* date: 2019/3/21 */

class exception_self extends

exception

//php的錯誤級別

public

static

$type = array

( '1' => 'e_error ',

'2' => 'e_warning ',

'4' => 'e_parse ',

'8' => 'e_notice ',

'16' => 'e_core_error ',

'32' => 'e_core_warning ',

'64' => 'e_compile_error ',

'128' => 'e_compile_warning ',

'256' => 'e_user_error ',

'512' => 'e_user_warning ',

'1024' => 'e_user_notice ',

'2048' => 'e_strict ',

'4096' => 'e_recoverable_error ',

'8191' => 'e_all ',);

/*** 通過數字 置換 對應的英文

* @param $key

* @return mixed

* user: lizheng [email protected]

* date: 2019/3/21

*/public

static

function get_type($key

)

else

}}

php錯誤和異常處理

php為異常處理提供了內建類 exception。其建構函式需要兩個引數 除了建構函式外,改類還提供了如下所示的內建方法 getcode 返回傳遞給建構函式的 getmessage 返回傳遞給建構函式的訊息 getfile 返回產生異常的 檔案的完整路徑 getline 返回 檔案中產生異常的 行號...

php 錯誤和異常處理

一 錯誤和異常處理 1.1錯誤型別和基本的除錯方法 php程式的錯誤發生一般歸屬於下列三個領域 語法錯誤 語法錯誤最常見,並且也容易修復。如 中遺漏乙個分號。這類錯誤會阻止指令碼的執行。執行時錯誤 這種錯誤一般不會阻止php指令碼的執行,但會阻止當前要做的事情。輸出一條錯誤,但php指令碼繼續執行 ...

php錯誤處理和php異常處理機制

php錯誤處理 當我們開發程式時,有時候程式出現了問題,我們就可以用以下幾種辦法找出錯誤。開發階段 開發時輸出所有的錯誤報告,有利於我們進行程式除錯 執行階段 我們不要讓程式輸出任何一種錯誤報告 不能讓使用者看到 包括懂技術,不懂技術的人 將錯誤報告寫入日誌中 一 指定錯誤報告 error repo...