PHP7 錯誤及異常機制


關鍵詞

  • 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");


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM