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

Yii 2.0 錯誤與異常處理機制深度解析:配置、自定義視圖、錯誤操作與格式化響應

     編輯:PHP 相關知識

Yii 2.0 錯誤與異常處理機制深度解析:配置、自定義視圖、錯誤操作與格式化響應

Yii 2 內建 yii\web\ErrorHandler 元件,統一接管 PHP 錯誤與未捕獲異常,支援開發/生產模式差異化顯示、自定義錯誤頁面、錯誤操作路由、JSON/API 錯誤格式化。本文系統拆解核心流程與配置實戰。

一、核心流程

  1. 入口腳本註冊處理器:set_error_handler()、set_exception_handler() 指向 ErrorHandler。
  2. 捕獲錯誤/異常 → 封裝為 yii\web\ErrorEvent / yii\web\ExceptionEvent。
  3. 記錄日誌(級別 error,分類 application / exception.ClassName)。
  4. 根據 YII_DEBUG 與 YII_ENV 決定顯示策略:
模式YII_DEBUG顯示內容
開發true完整堆疊追蹤、原始碼片段、變數值
生產false友好錯誤頁面,隱藏敏感信息

二、錯誤處理器配置

// config/web.php
return [
    'components' => [
        'errorHandler' => [
            'class' => 'yii\web\ErrorHandler',
            'maxSourceLines' => 20,          // 異常頁顯示原始碼行數
            'errorAction' => 'site/error',   // 指定錯誤操作路由(推薦)
            // 'errorView' => '@app/views/errorHandler/error.php',      // 自定義錯誤視圖
            // 'exceptionView' => '@app/views/errorHandler/exception.php', // 自定義異常視圖
        ],
    ],
];

三、使用錯誤操作(推薦方式)

1. 控制器定義 actions()

namespace app\controllers;
use Yii;
use yii\web\Controller;

class SiteController extends Controller {
    public function actions() {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
        ];
    }
}

2. 或手寫 actionError()

public function actionError() {
    $exception = Yii::$app->errorHandler->exception;
    if ($exception !== null) {
        return $this->render('error', ['exception' => $exception]);
    }
}

3. 視圖文件 views/site/error.php

<?php
use yii\helpers\Html;
/* @var $exception \yii\web\HttpException|Exception */
?>
<div class="error-page">
    <h1><?= Html::encode($exception->getMessage()) ?></h1>
    <p>錯誤代碼:<?= $exception->getCode() ?></p>
    <p>狀態碼:<?= $exception->statusCode ?? 500 ?></p>
    <a href="<?= Yii::$app->homeUrl ?>">返回首頁</a>
</div>

四、主動拋出 HTTP 異常

use yii\web\NotFoundHttpException;
use yii\web\ForbiddenHttpException;
use yii\web\BadRequestHttpException;

throw new NotFoundHttpException('頁面不存在');        // 404
throw new ForbiddenHttpException('權限不足');           // 403
throw new BadRequestHttpException('參數錯誤');          // 400
throw new \yii\web\ServerErrorHttpException('服務器錯誤'); // 500

ErrorHandler 會自動設置正確的 HTTP 狀態碼並渲染對應視圖。

五、PHP 錯誤轉異常捕獲

use Yii;
use yii\base\ErrorException;

try {
    10 / 0; // 觸發 E_WARNING
} catch (ErrorException $e) {
    Yii::warning("Division by zero: " . $e->getMessage());
}
// 程式繼續執行...

非致命 PHP 錯誤(E_WARNING、E_NOTICE 等)自動轉為 ErrorException 可被 try-catch 捕獲。

六、自定義錯誤響應格式(API 專用)

根據 Response::format 自動格式化:

  • html:渲染視圖(上述流程)。
  • json/xml:返回結構化數據。
// JSON 格式錯誤響應範例
{
    "name": "Not Found Exception",
    "message": "The requested resource was not found.",
    "code": 0,
    "status": 404
}

統一包裝 API 錯誤格式

// config/web.php
'components' => [
    'response' => [
        'class' => 'yii\web\Response',
        'on beforeSend' => function ($event) {
            $response = $event->sender;
            if ($response->data !== null && !$response->isSuccessful) {
                $response->data = [
                    'success' => false,
                    'error' => [
                        'code' => $response->statusCode,
                        'message' => $response->data['message'] ?? 'Internal Server Error',
                        'details' => $response->data,
                    ],
                ];
                $response->statusCode = 200; // 統一返回 200,前端靠 success 判斷
            }
        },
    ],
],

最終輸出:

{
    "success": false,
    "error": {
        "code": 404,
        "message": "The requested resource was not found.",
        "details": { "name": "...", "message": "...", "code": 0, "status": 404 }
    }
}

七、UserException:業務異常不顯示堆疊

繼承 yii\base\UserException 的異常,**無論 YII_DEBUG 如何**,都不顯示堆疊追蹤,視為用戶操作錯誤而非程式 Bug。

class InsufficientBalanceException extends \yii\base\UserException {}
throw new InsufficientBalanceException('餘額不足'); // 生產環境也只顯示訊息

八、最佳實踐總結

  1. 生產環境必須設定 errorAction,避免暴露堆疊追蹤。
  2. API 專案統一格式化錯誤響應,前端統一處理。
  3. 業務邏輯錯誤拋出 UserException 子類,區分 Bug 與用戶錯誤。
  4. 關鍵路徑 try-catch 記錄警告日誌,便於事後分析。
  5. 定期審查 runtime/logs/app.log,發現潛在異常模式。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved