完善的錯誤處理是專業級 PHP 應用的基石。本文系統梳理 PHP 錯誤處理的四個層次:基礎終止、自定義處理器、錯誤觸發與日誌記錄,並提供可直接落地的最佳實踐代碼。
最簡單的防禦性編程:
// 不推薦:直接輸出警告給用戶
$file = fopen("welcome.txt", "r");
// 推薦:檢查後友好終止
if (!file_exists("welcome.txt")) {
die("File not found");
}
$file = fopen("welcome.txt", "r");
缺點:粗暴終止腳本,無法記錄日誌、無法優雅降級、難以維護。
建立統一錯誤處理入口:
function customError($errno, $errstr, $errfile = '', $errline = 0, $errcontext = []) {
// 格式化錯誤訊息
$msg = "Error: [$errno] $errstr in $errfile on line $errline
";
// 根據嚴重程度決定行為
if (in_array($errno, [E_USER_ERROR, E_RECOVERABLE_ERROR])) {
$msg .= "Fatal error - Script terminated";
error_log($msg, 0); // 寫入系統日誌
die($msg);
}
// 非致命錯誤僅記錄
error_log($msg, 0);
echo $msg; // 開發環境顯示,生產環境可關閉
}
// 註冊為預設處理器
set_error_handler("customError");
在業務邏輯驗證失敗時主動拋出錯誤:
$test = 2;
if ($test > 1) {
// 觸發用戶級警告,交由 customError 處理
trigger_error("Value must be 1 or below", E_USER_WARNING);
}
常用錯誤類型常量:
| 常量 | 值 | 說明 |
|---|---|---|
| E_USER_ERROR | 256 | 致命用戶錯誤,腳本終止 |
| E_USER_WARNING | 512 | 非致命用戶警告,腳本繼續 |
| E_USER_NOTICE | 1024 | 用戶提示訊息 |
| E_RECOVERABLE_ERROR | 4096 | 可捕獲的致命錯誤 |
function customError($errno, $errstr, $errfile, $errline) {
$msg = "[$errno] $errstr in $errfile:$errline";
// 1. 寫入本地日誌
error_log($msg, 3, "/var/log/php_app_error.log");
// 2. 致命錯誤發送郵件通知運維
if ($errno === E_USER_ERROR) {
error_log($msg, 1, "ops@example.com", "From: noreply@example.com");
}
// 3. 開發環境顯示詳情
if (ini_get('display_errors')) {
echo "Error: $msg
";
}
}
PHP 7+ 建議使用 try-catch + Throwable 接口:
try {
// 業務代碼
if ($invalid) throw new InvalidArgumentException("參數無效");
} catch (Throwable $e) {
// 統一異常處理:記錄、回滾、返回友好響應
error_log($e->getMessage());
http_response_code(500);
echo json_encode(['error' => '系統內部錯誤']);
}
建立分層錯誤處理體系,能讓應用在面對預期與非預期錯誤時,都能「有據可查、有邏輯可循、有機制可控」。