首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 自定義錯誤處理器:set_error_handler() 完整實作指南

     編輯:PHP 相關知識

PHP 自定義錯誤處理器:set_error_handler() 完整實作指南

PHP 預設錯誤輸出格式單一,難以滿足生產環境需求(記錄日誌、郵件通知、友善錯誤頁面)。透過 set_error_handler() 註冊自定義處理函數,可完全掌控錯誤處理流程。

核心實作範例

<?php
// 開啟所有錯誤報告
error_reporting(E_ALL);

/**
 * 自定義錯誤處理器
 *
 * @param int    $errno   錯誤層級
 * @param string $errstr  錯誤訊息
 * @param string $errfile 發生錯誤的檔案
 * @param int    $errline 發生錯誤的行號
 * @return bool  true 表示已處理,不再執行內建處理器
 */
function customErrorHandler(int $errno, string $errstr, string $errfile, int $errline): bool {
    // 定義錯誤層級標籤與處理策略
    $config = [
        E_ERROR             => ['label' => 'Fatal Error',      'halt' => true,  'log' => true,  'notify' => true],
        E_WARNING           => ['label' => 'Warning',          'halt' => false, 'log' => true,  'notify' => false],
        E_PARSE             => ['label' => 'Parse Error',      'halt' => true,  'log' => true,  'notify' => true],
        E_NOTICE            => ['label' => 'Notice',           'halt' => false, 'log' => true,  'notify' => false],
        E_CORE_ERROR        => ['label' => 'Core Error',       'halt' => true,  'log' => true,  'notify' => true],
        E_CORE_WARNING      => ['label' => 'Core Warning',     'halt' => false, 'log' => true,  'notify' => false],
        E_COMPILE_ERROR     => ['label' => 'Compile Error',    'halt' => true,  'log' => true,  'notify' => true],
        E_COMPILE_WARNING   => ['label' => 'Compile Warning',  'halt' => false, 'log' => true,  'notify' => false],
        E_USER_ERROR        => ['label' => 'User Error',       'halt' => true,  'log' => true,  'notify' => true],
        E_USER_WARNING      => ['label' => 'User Warning',     'halt' => false, 'log' => true,  'notify' => false],
        E_USER_NOTICE       => ['label' => 'User Notice',      'halt' => false, 'log' => true,  'notify' => false],
        E_STRICT            => ['label' => 'Strict',           'halt' => false, 'log' => true,  'notify' => false],
        E_RECOVERABLE_ERROR => ['label' => 'Catchable Error',  'halt' => true,  'log' => true,  'notify' => true],
        E_DEPRECATED        => ['label' => 'Deprecated',       'halt' => false, 'log' => true,  'notify' => false],
        E_USER_DEPRECATED   => ['label' => 'User Deprecated',  'halt' => false, 'log' => true,  'notify' => false],
    ];

    $cfg = $config[$errno] ?? ['label' => 'Unknown', 'halt' => false, 'log' => true, 'notify' => false];

    $msg = sprintf(
        "[%s] %s in %s on line %d\n",
        $cfg['label'],
        $errstr,
        $errfile,
        $errline
    );

    // 記錄日誌
    if ($cfg['log']) {
        error_log($msg, 3, __DIR__ . '/logs/php_errors.log'); // 寫入檔案
    }

    // 開發環境顯示錯誤
    if (isset($_SERVER['APP_ENV']) && $_SERVER['APP_ENV'] === 'development') {
        echo "
" . htmlspecialchars($msg) . "
"; } // 發送通知(如 Email、Slack) if ($cfg['notify']) { // mail('admin@example.com', 'PHP Error Alert', $msg); } // 嚴重錯誤中止腳本 if ($cfg['halt']) { // 可在這裡載入友善錯誤頁面 // include __DIR__ . '/templates/500.php'; exit(1); } return true; // 表示已處理,不再呼叫內建處理器 } // 註冊處理器 set_error_handler('customErrorHandler'); // 測試觸發各類錯誤 trigger_error('這是使用者 Notice', E_USER_NOTICE); trigger_error('這是使用者 Warning', E_USER_WARNING); trigger_error('這是使用者 Error', E_USER_ERROR); // trigger_error('這是 Parse Error', E_PARSE); // Parse Error 無法由 trigger_error 產生 ?>

關鍵點說明

  • 回傳值: 處理器回傳 true 表示「已處理」,PHP 將不再執行內建錯誤處理;回傳 false 或無回傳則繼續內建流程。
  • 無法捕獲的錯誤: E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING 以及 set_error_handler() 註冊前發生的錯誤,無法被自定義處理器捕獲。需配合 register_shutdown_function() 捕獲致命錯誤。
  • 錯誤層級常數: 使用位元運算可組合層級,如 E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED。
  • 例外處理: PHP 7+ 將大多數錯誤轉為 Error 例外,建議搭配 set_exception_handler() 統一處理。

進階:整合 Monolog 等日誌庫

<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$log = new Logger('app');
$log->pushHandler(new StreamHandler(__DIR__ . '/logs/app.log', Logger::WARNING));

function modernErrorHandler($errno, $errstr, $errfile, $errline) {
    global $log;
    $log->error($errstr, [
        'file' => $errfile,
        'line' => $errline,
        'level' => $errno,
        'trace' => debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5)
    ]);
    return true;
}
set_error_handler('modernErrorHandler');
?>

總結

自定義錯誤處理器是建立健壯 PHP 應用的關鍵一環。結合日誌記錄、環境區分、通知機制與友善錯誤頁面,可大幅提升系統可觀測性與使用者體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved