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();
}
?>