PHP 錯誤處理與日誌記錄完整指南
簡介
PHP 提供完整的錯誤處理與日誌機制:自訂錯誤處理器、例外處理器、觸發使用者錯誤、記錄至檔案/系統日誌/郵件、錯誤報告層級控制、顯示/隱藏錯誤等。所有函數內建核心,無需安裝。
執行期設定 (php.ini 關鍵指令)
| 指令 | 預設值 | 說明 | 可變範圍 |
| error_reporting | NULL | 設定錯誤報告層級 (數值或常數) | PHP_INI_ALL |
| display_errors | "1" | 是否將錯誤輸出到畫面 (生產環境應關閉) | PHP_INI_ALL |
| display_startup_errors | "0" | 啟動階段錯誤是否顯示 (建議關閉) | PHP_INI_ALL |
| log_errors | "0" | 是否記錄錯誤到伺服器日誌或 error_log | PHP_INI_ALL |
| log_errors_max_len | "1024" | 錯誤日誌最大長度 (0 為不限) | PHP_INI_ALL |
| ignore_repeated_errors | "0" | 不記錄重複錯誤 (同檔同行) | PHP_INI_ALL |
| ignore_repeated_source | "0" | 忽略重複來源 | PHP_INI_ALL |
| report_memleaks | "1" | 顯示記憶體洩漏資訊 | PHP_INI_ALL |
| track_errors | "0" | 最後一個錯誤存入 $php_errormsg | PHP_INI_ALL |
| html_errors | "1" | 錯誤訊息包含 HTML 標籤 | PHP_INI_ALL |
| error_log | NULL | 指定錯誤日誌檔案路徑 (需 Web 使用者可寫) | PHP_INI_ALL |
核心函數
| 函數 | 說明 | PHP 版本 |
error_reporting() | 設定/取得錯誤報告層級 | 4 |
set_error_handler() | 設定使用者自訂錯誤處理函數 | 4 |
restore_error_handler() | 恢復上一個錯誤處理器 | 4 |
set_exception_handler() | 設定使用者自訂例外處理函數 | 5 |
restore_exception_handler() | 恢復上一個例外處理器 | 5 |
trigger_error() / user_error() | 觸發使用者自訂錯誤/警告/通知 | 4 |
error_log() | 發送錯誤到伺服器日誌、檔案或遠端 | 4 |
error_get_last() | 取得最後發生的錯誤資訊陣列 | 5 |
debug_backtrace() | 生成回溯追蹤陣列 | 4 |
debug_print_backtrace() | 列印回溯追蹤 | 5 |
錯誤層級常數
| 值 | 常數 | 說明 | PHP 版本 |
| 1 | E_ERROR | 執行期致命錯誤,腳本終止 | |
| 2 | E_WARNING | 執行期非致命警告 | |
| 4 | E_PARSE | 編譯期解析錯誤 | |
| 8 | E_NOTICE | 執行期通知 (潛在問題) | |
| 16 | E_CORE_ERROR | PHP 啟動致命錯誤 | 4 |
| 32 | E_CORE_WARNING | PHP 啟動警告 | 4 |
| 64 | E_COMPILE_ERROR | 編譯致命錯誤 (Zend 引擎) | 4 |
| 128 | E_COMPILE_WARNING | 編譯警告 | 4 |
| 256 | E_USER_ERROR | 使用者觸發致命錯誤 | 4 |
| 512 | E_USER_WARNING | 使用者觸發警告 | 4 |
| 1024 | E_USER_NOTICE | 使用者觸發通知 | 4 |
| 2048 | E_STRICT | 程式碼相容性建議 | 5 |
| 4096 | E_RECOVERABLE_ERROR | 可捕獲的致命錯誤 (可由 set_error_handler 處理) | 5 |
| 6143 | E_ALL | 所有錯誤與警告 (PHP 6 起包含 E_STRICT) | 5 |
最佳實踐範例
1. 開發環境完整錯誤顯示
<?php
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
?>
2. 生產環境記錄不顯示
<?php
ini_set('display_errors', '0');
ini_set('log_errors', '1');
ini_set('error_log', '/var/log/php/error.log');
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);
?>
3. 自訂錯誤處理器 (將錯誤轉為例外)
<?php
function exceptionErrorHandler($severity, $message, $file, $line) {
if (!(error_reporting() & $severity)) return;
throw new ErrorException($message, 0, $severity, $file, $line);
}
set_error_handler('exceptionErrorHandler');
try {
// 程式碼...
} catch (ErrorException $e) {
error_log($e->getMessage());
// 友善錯誤頁面
}
?>
4. 記錄自訂錯誤到檔案
<?php
error_log("訂單處理失敗: OrderID=$orderId", 3, "/var/log/app/orders.log");
?>
關鍵建議
- 生產環境 絕不 開啟
display_errors,避免洩露敏感資訊。
- 統一使用例外處理,配合
set_exception_handler 進行全域捕獲與記錄。
- 日誌檔案權限確保 Web 使用者可寫,並定期輪轉 (logrotate)。
- 使用
error_get_last() 在關閉腳本前檢查致命錯誤 (register_shutdown_function)。