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

PHP try-catch 異常處理完整指南:基礎語法、多重捕獲、自訂異常、最佳實踐

     編輯:PHP 綜合知識

前言

PHP 5 引入物件導向異常模型,try-catch 取代傳統錯誤碼檢查,讓錯誤處理更結構化。本文從語法到進階模式完整說明。

基礎語法

<?php
try {
    // 可能拋出異常的程式碼
    $result = riskyOperation();
} catch (Exception $e) {
    // 捕獲 Exception 及其子類
    logError($e->getMessage());
    showFriendlyMessage('系統繁忙,請稍後再試');
} finally { // PHP 5.5+
    // 無論是否異常都會執行 (關閉連線、釋放鎖)
    cleanup();
}

關鍵規則

  • throw 拋出後,當前 try 區塊立即中止,跳往匹配的 catch。
  • 至少一個 catch,可多個捕獲不同型別 (子類優先)。
  • 若無匹配 catch 且未設定 set_exception_handler(),致命錯誤 Uncaught Exception。
  • catch 區塊可再次 throw (重新拋出或包裝新異常)。

多重捕獲範例

<?php
class MyException extends Exception {
    public function __construct($message, $code = 0) {
        parent::__construct($message, $code);
    }
    public function __toString() {
        return __CLASS__ . ":[{$this->code}]:{$this->message}";
    }
    public function customHandler() { echo "自訂處理: {$this->message}"; }
}

class Service {
    public function doAction($mode) {
        switch ($mode) {
            case 1: throw new MyException('模式1錯誤', 1001);
            case 2: throw new InvalidArgumentException('模式2參數錯誤');
            default: return 'OK';
        }
    }
}

try {
    $svc = new Service();
    echo $svc->doAction(1);
} catch (MyException $e) {
    echo "捕獲自訂異常: $e";
    $e->customHandler();
} catch (Exception $e) {
    echo "捕獲標準異常: {$e->getMessage()}";
}

實務場景:檔案載入與資源釋放

<?php
// 錯誤示範:require 失敗不拋出 Exception,只產生 Warning
try {
    require 'missing.php'; // 不會進入 catch
} catch (Exception $e) { }

// 正確做法:手動檢查並拋出
try {
    $file = 'config.php';
    if (!file_exists($file)) {
        throw new RuntimeException("配置檔不存在: $file");
    }
    require $file;
} catch (Exception $e) {
    error_log($e->getMessage());
    die('系統初始化失敗');
}

進階模式

1. 異常包裝 (保留原始堆疊)

try {
    $pdo->query($sql);
} catch (PDOException $e) {
    throw new RepositoryException('資料庫查詢失敗', 0, $e); // 第三參數 previous
}

2. 全域例外處理器 (最後防線)

set_exception_handler(function (Throwable $e) {
    http_response_code(500);
    logError($e);
    echo json_encode(['error' => 'Internal Server Error']);
    // 生產環境不輸出堆疊
});

3. 型別提示捕獲 Throwable (PHP 7+)

try { ... } catch (Throwable $e) { // 捕獲 Exception + Error
    // 統一處理所有可拋出物件
}

最佳實踐清單

  1. 僅對可預期、可恢復的錯誤用 try-catch (如 API 呼叫失敗、檔案不存在)。
  2. 程式錯誤 (型別錯誤、邏輯 Bug) 讓它拋出,由全域處理器記錄並顯示 500。
  3. 自訂異常類繼承 Exception,命名以 XxxException 結尾,方便分類捕獲。
  4. finally 用於資源釋放 (關閉檔案、資料庫連線、釋放鎖)。
  5. 不要用異常控制正常流程 (如 if 判斷即可)。
  6. 記錄異常時務必包含 $e->getTraceAsString() 完整堆疊。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved