關鍵詞
- error 不能在編譯期發現的運行期錯誤,比如試圖用 echo 輸出一個未賦值的變量,這類問題往往導致程序或邏輯無法繼續下去而需要中斷;
- exception 程序執行過程中出現意料之外的情況,邏輯上往往是行得通的,但不符合應用場景,比如接收到一個長度超出預定格式的用戶命名,因此,異常主要靠編碼人員做預先做判斷后拋出,捕獲異常后改變程序流程來處理這些情況,不必中斷程序。
- error_reporting 設置錯誤的報告級別,返回給客戶端
- display_errors 設置是否將錯誤展示給客戶端
- log_errors 設置是否記錄錯誤日志
- error_log 設置錯誤日志記錄路徑
- try-catch
- trigger_error 用戶主動觸發的錯誤
- set_error_handler 自定義 error 處理邏輯,可以捕獲絕大部分的 error,如果自定義函數 return false,則處理邏輯結束后,程序是否結束取決於 error 的情況(即是否繼續執行取決於其他設置),如果不 return false,則處理邏輯結束后,程序正常運行 error 之后的代碼。但是以下級別的錯誤不能由用戶定義的函數來處理: E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPILE_WARNING,和在 調用 set_error_handler() 函數所在文件中產生的大多數 E_STRICT。
- set_exception_handler 自定義 exception 的處理邏輯,當發現某個 exception 沒有被 catch 的時候,就會調用這個函數,不管這個自定義的異常處理邏輯運行狀況如何,在異常處理完之后,程序一定會被中斷
- register_shutdown_function 自定義的程序結束邏輯處理,不管是否正常結束,是否進入了 set_error_handler 和 set_exception_handler 都將在程序結束前執行這段自定義邏輯,未捕獲的 error(一般未捕獲的 error 都會導致程序中斷),可以在這里進行處理
概述
php7 相比 5.6,對於異常和錯誤做了一些改進,原來的一些 fatal error 在 7.0 以后版本都被作為 error 拋出,可以使用 try-catch 進行捕獲處理。
感覺 php 中對於 error 和 exception 的定義比較模糊
一段測試 php7 的異常處理邏輯代碼
<?php
/**
* test.php
*/
function getBackTraceStr() {
ob_start();
debug_print_backtrace();
$trace = ob_get_contents();
ob_end_clean();
return $trace;
}
function _exceptionHandler($e) {
var_dump($e);
}
function check_for_fatal()
{
var_dump("end");
$error = error_get_last();
var_dump($error);
}
function _errorHandler($errNo, $errStr, $errFile, $errLine) {
var_dump($errNo);
var_dump($errStr);
var_dump($errFile);
var_dump($errLine);
$trace = getBackTraceStr();
var_dump($trace);
throw new ErrorException($errStr, 0, $errNo, $errFile, $errLine);
}
set_error_handler("_errorHandler");
set_exception_handler("_exceptionHandler");
register_shutdown_function("check_for_fatal");
error_reporting(E_USER_ERROR);
error_reporting(E_ALL);
ini_set('display_errors', "on");
ini_set('log_errors', "on");
var_dump(error_reporting());
$a = E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED;
$b = 1 % 0;
try {
$a->nonexist();
$b = 1 / 0;
trigger_error("fuck", E_USER_ERROR);
throw new Exception("abc");
} catch(Throwable $e) {
var_dump($e);
}
trigger_error("fuck", E_USER_ERROR);
require("abc.json");
throw new Exception("abc");
noexist(3, 54);
try {
require("abc.json");
} catch (Error $e) {
var_dump("what");
}
define("hello", 1);
define("hello", 1);
var_dump("a");