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

PHP 利用 register_shutdown_function 捕獲 Fatal Error 並友善回饋

     編輯:PHP 綜合知識

問題背景

生產環境通常關閉 display_errors,若發生 Fatal Error(如呼叫未定義類別、require 不存在檔案),使用者只會看到空白頁面,體驗極差。我們需要一個機制,在腳本異常終止前介入,輸出友善的錯誤訊息或記錄日誌。

解決方案:register_shutdown_function

register_shutdown_function 註冊的回調會在腳本執行結束(正常結束或因致命錯誤中止)前自動執行。搭配旗標變數即可判斷是否發生 Fatal Error。

核心實作範例

<?php
$isNormalExit = false; // 全域旗標,預設為異常結束

function shutdownHandler(): void
{
    global $isNormalExit;
    if (!$isNormalExit) {
        // 這裡可記錄錯誤日誌、發送告警、輸出友善頁面
        // 注意:此階段無法再拋出例外或使用 die()/exit()
        http_response_code(500);
        echo '<h1>系統暫時無法服務,請稍後再試</h1>';
        // error_log('Fatal Error 發生於 ' . date('Y-m-d H:i:s'));
    }
}

register_shutdown_function('shutdownHandler');

// ---- 業務邏輯區 ----
// 模擬 Fatal Error:require 不存在的檔案、實例化未定義類別
// require './not_exist.php'; 
// $obj = new NotExistClass(); 

// 正常執行完畢,標記旗標
$isNormalExit = true;

進階技巧:獲取錯誤詳細資訊

function shutdownHandler(): void
{
    global $isNormalExit;
    if (!$isNormalExit) {
        $error = error_get_last();
        if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
            // 記錄完整錯誤堆疊
            error_log(sprintf(
                "[FATAL] %s in %s on line %d",
                $error['message'],
                $error['file'],
                $error['line']
            ));
        }
        // 輸出使用者友善頁面
        include __DIR__ . '/templates/500.php';
    }
}

注意事項

  • 無法捕獲:語法錯誤(Parse Error)在編譯階段即終止,不會觸發 shutdown。
  • 輸出緩衝:若已有輸出,需搭配 ob_start() 控制輸出內容。
  • 資源釋放:關閉階段資源(DB 連線等)可能已釋放,避免在回調中使用。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved