PHP 錯誤處理 (Error Handling)
PHP 提供多種方式處理程式執行時的錯誤。
錯誤類型
| 類型 | 說明 |
|---|---|
E_ERROR | 致命錯誤,程式停止 |
E_WARNING | 警告,程式繼續 |
E_NOTICE | 提示,程式繼續 |
E_PARSE | 語法錯誤 |
E_DEPRECATED | 棄用警告 |
錯誤回報設定
<?php
// 顯示所有錯誤(開發環境)
error_reporting(E_ALL);
ini_set('display_errors', '1');
// 隱藏錯誤,記錄到日誌(正式環境)
error_reporting(E_ALL);
ini_set('display_errors', '0');
ini_set('log_errors', '1');
ini_set('error_log', '/path/to/error.log');
?>
自訂錯誤處理
<?php
function customErrorHandler($errno, $errstr, $errfile, $errline) {
$message = "[$errno] $errstr in $errfile on line $errline";
error_log($message);
// 根據錯誤類型處理
switch ($errno) {
case E_WARNING:
case E_NOTICE:
return true; // 繼續執行
default:
echo "發生錯誤,請稍後再試";
exit(1);
}
}
set_error_handler('customErrorHandler');
?>
觸發錯誤
<?php
function divide($a, $b) {
if ($b === 0) {
trigger_error("除數不能為零", E_USER_WARNING);
return null;
}
return $a / $b;
}
$result = divide(10, 0); // 觸發警告
?>
抑制錯誤
<?php
// 使用 @ 抑制錯誤(不建議)
$result = @file_get_contents('nonexistent.txt');
// 更好的方式:先檢查
if (file_exists('data.txt')) {
$content = file_get_contents('data.txt');
}
?>
關閉處理器
<?php
function shutdownHandler() {
$error = error_get_last();
if ($error !== null && in_array($error['type'], [E_ERROR, E_PARSE])) {
error_log("Fatal error: {$error['message']} in {$error['file']}");
echo "系統發生嚴重錯誤";
}
}
register_shutdown_function('shutdownHandler');
?>
斷言(Assert)
<?php
// 啟用斷言
assert_options(ASSERT_ACTIVE, true);
assert_options(ASSERT_EXCEPTION, true);
function processAge(int $age): void {
assert($age >= 0 && $age <= 150, '年齡必須在 0-150 之間');
// 處理...
}
try {
processAge(-5);
} catch (AssertionError $e) {
echo $e->getMessage();
}
?>
最佳實踐
<?php
// 開發環境設定
function setupDevelopment(): void {
error_reporting(E_ALL);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
}
// 正式環境設定
function setupProduction(): void {
error_reporting(E_ALL);
ini_set('display_errors', '0');
ini_set('log_errors', '1');
ini_set('error_log', '/var/log/php/error.log');
set_error_handler(function($errno, $errstr, $errfile, $errline) {
error_log("[$errno] $errstr in $errfile:$errline");
return false;
});
register_shutdown_function(function() {
$error = error_get_last();
if ($error && $error['type'] === E_ERROR) {
http_response_code(500);
echo '系統發生錯誤';
}
});
}
// 根據環境選擇
if (getenv('APP_ENV') === 'production') {
setupProduction();
} else {
setupDevelopment();
}
?>