PHP 主要有兩種錯誤:觸發錯誤和異常。其中觸發錯誤大概能夠分爲:編譯錯誤、引擎錯誤和運行時錯誤,其中前兩個是沒法捕獲的;異常都是能夠捕獲的,當沒有嘗試捕獲時則會中斷代碼。php
觸發錯誤能夠經過 error_get_last()
來進行得到,異常可使用標準的 try...catch
語句來捕獲。編程
error_reporting() 函數是 PHP 提供的一個控制錯誤等級的函數,若是設置了對應的錯誤等級,則只會在對應錯誤等級觸發時纔會在頁面(或輸出,對於命令行來講)輸出響應的錯誤信息。網絡
error_reporting(int level) 支持等級 level 參數使用二進制的數字來配置錯誤等級,錯誤等級通常用常量來代替對應的二進制標識。例如:E_ALL、E_NOTICE、 E_USER_NOTICE 等等;若是不傳遞參數,則會返回當前的錯誤等級(通常用來保存當前的錯誤等級以供後續恢復)。函數
其中 E_PARSE、E_COMPILE_* 和 E_CORE_* 是非運行時錯誤,沒法被捕獲的spa
配置文件是 PHP 初始化的默認
配置,經過修改某些參數能夠控制對應的初始化參數。若是要控制錯誤,能夠經過如下幾個方式來配置:命令行
display_errors - 是否顯示錯誤,通常在生產環境建議關閉該參數並和下列的參數一塊兒試用 log_errors - 記錄錯誤開關,若是打開會記錄到對應位置 error_log - 記錄錯誤日誌的位置,不指定爲系統默認 error_reporting - 同上面的函數rest
PHP 提供了一種特殊的操做,經過在語句前面加上抑制錯誤操做符@
來抑制該語句出現錯誤。這種狀況一般用於你不知道會發生什麼狀況下使用,好比打開了不肯定的文件或者網絡 URL,但通常不推薦使用日誌
抑制錯誤自己內部作了一系列的處理才達到該效果,而且對於錯誤自己徹底是未知的,通常狀況下,不建議這麼使用code
幾乎在全部語言中,都會有對於異常的處理。若是程序拋出一個異常,那麼能夠經過 try…catch 語句來捕獲該異常,若是明確知道錯誤的類型,也能夠只捕獲該類型的錯誤。try…catch 是一種最標準的錯誤處理方式對象
1 2 3 4 5 |
try { // 代碼部分 } catch (Exception $e) { // 根據異常對象對 $e 進行處理 } |
PHP 提供了 set_error_handler() 函數來讓開發者傳入一個函數名(或匿名函數,對於 5.2 以上的 PHP)就可讓全部的錯誤進入該函數,而後開發者能夠在函數內進行控制,舉例說明
1 2 3 |
set_error_handler(function($code, $msg){ log_error("$msg occur with code $code"); }); |
對應地,PHP 也提供了 restore_error_handler() 來恢復爲標準的 PHP 錯誤控制。
若是每一個異常都去捕獲,顯然是很複雜的事情,須要編寫不少代碼,並且維護起來會比較複雜,對於一個快速編程的語言來講,PHP 天然不會容許發生這種事情。使用 set_exception_handler() 就能夠像上面錯誤處理控制器同樣接收全部未捕獲的異常,而後作一些該作的事情,甚至還能夠再把錯誤拋出來。例如:
1 2 3 |
set_exception_handler(function($exception){ log_error("Exception occur: $exception"); }); |
該類處理並不是 PHP 標準的處理方式,但對於某種使程序崩潰的沒法捕獲的錯誤確實頗有用,它是指註冊一個 shutdown 函數,在函數內經過調用 error_get_last() 來獲取最後的錯誤,而且根據錯誤等級來作相應的處理。
1 2 3 4 5 6 |
register_shutdown_function(function(){ $error = error_get_last(); if ($error && $error['code']()() & error_reporting()) { // 崩潰錯誤,記錄日誌 } }); |