欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

實(shí)例講解如何在PHP的Yii框架中進(jìn)行錯(cuò)誤和異常處理

 更新時(shí)間:2016年03月17日 16:00:51   作者:柏樹_Jeff  
這篇文章主要介紹了如何在PHP的Yii框架中進(jìn)行錯(cuò)誤和異常處理的實(shí)例,重點(diǎn)講解了使用錯(cuò)誤處理器的方法,需要的朋友可以參考下

Yii已經(jīng)默認(rèn)已經(jīng)在CApplication上實(shí)現(xiàn)了異常和錯(cuò)誤的接管,這是通過(guò)php的set_exception_handler,set_error_handler實(shí)現(xiàn)的。通過(guò)這兩個(gè)PHP內(nèi)置函數(shù),可以對(duì)程序中未捕獲的異常以及錯(cuò)誤進(jìn)行接管處理,從而提高程序的可維護(hù)性。這在大型系統(tǒng)是至關(guān)重要的,當(dāng)發(fā)生錯(cuò)誤時(shí),我們希望能將相關(guān)詳細(xì)信息記錄,甚至是即時(shí)發(fā)送報(bào)警,從而縮短故障修復(fù)時(shí)間,提高整個(gè)系統(tǒng)的穩(wěn)定性。
默認(rèn)情況下,Yii會(huì)將異常處理分配給CApplication::handleException, 將錯(cuò)誤處理分配給CApplication::handleError,但是可以通過(guò)在入口文件中定義YII_ENABLE_EXCEPTION_HANDLER, YII_ENABLE_ERROR_HANDLER兩個(gè)常量為false禁止使用Yii的異常和錯(cuò)誤接管機(jī)制。
以下內(nèi)容中,將異常和錯(cuò)誤統(tǒng)稱為錯(cuò)誤,如有必要會(huì)進(jìn)行詳細(xì)區(qū)分說(shuō)明。YII_DEBUG常量(默認(rèn)為false, 可以在入口文件中設(shè)置)對(duì)錯(cuò)誤信息的顯示有很重要的影響,debug模式下,錯(cuò)誤的輸出是最詳細(xì)的。而程序一旦投入運(yùn)行,則應(yīng)將YII_DEBUG修改為false。
無(wú)論是否處于debug模式,Yii程序產(chǎn)生錯(cuò)誤時(shí)均會(huì)將相關(guān)錯(cuò)誤信息進(jìn)行記錄(錯(cuò)誤級(jí)別為error, 分類默認(rèn)為application)。不同之處是debug模式時(shí)會(huì)直接在web頁(yè)上顯示詳細(xì)信息。

CApplication:: handleError($code,$message,$file,$line)

上面的方法實(shí)現(xiàn)了相關(guān)邏。特別注意restore_error_handler,restore_exception_handler兩個(gè)函數(shù),如果沒(méi)有這兩個(gè)函數(shù)的調(diào)用,那么在后續(xù)的錯(cuò)誤處理過(guò)程中,當(dāng)再次產(chǎn)生異?;蚴清e(cuò)誤時(shí),又會(huì)調(diào)用CApplication:: handleError ,從而可能造成死循環(huán),故Yii在此處臨時(shí)禁止了使用CApplication:: handleError 接管后續(xù)的錯(cuò)誤和異常(使用php默認(rèn)的錯(cuò)誤處理機(jī)制),這就保證了不會(huì)因之產(chǎn)生循環(huán)調(diào)用。
PHP錯(cuò)誤的處理當(dāng)產(chǎn)生錯(cuò)誤時(shí),PHP會(huì)在日志中記錄哪些信息?錯(cuò)誤代碼(即PHP的E_ERROR E_WARNING  E_STRICT E_DEPRECATED)消息內(nèi)容(如 Undefined vaiable $input)產(chǎn)生錯(cuò)誤的文件路徑產(chǎn)生錯(cuò)誤的行號(hào)額外的跟蹤回溯信息(這是通過(guò)debug_backtrace實(shí)現(xiàn)的)當(dāng)前URL
除了記錄相應(yīng)日志之外,Yii還會(huì)對(duì)錯(cuò)誤進(jìn)行后續(xù)處理(如中斷運(yùn)行、顯示錯(cuò)誤頁(yè)等),默認(rèn)情況下錯(cuò)誤的處理會(huì)交給CErrorHandler組件處理(但可以通過(guò)給CApplicaton綁定onError事件處理器而實(shí)現(xiàn)錯(cuò)誤處理的二次接管,此處的設(shè)計(jì)很靈活?。?。
此時(shí)將產(chǎn)生一個(gè)CErrorEvent(并包含$code,$message,$file,$line幾項(xiàng)關(guān)鍵參數(shù)),傳遞給CErrorHandler組件進(jìn)行處理。具體是交給CErrorHandler::handleError處理之。這個(gè)流程主要是將錯(cuò)誤相關(guān)信息進(jìn)行整理,并以合適的方式進(jìn)行顯示。
是否為debug模式(YII_DEBUG==true),對(duì)錯(cuò)誤信息的顯示結(jié)果有極大影響。調(diào)試模式下我們希望能顯示詳細(xì)的錯(cuò)誤跟蹤信息,而在生產(chǎn)模式下,我們希望給用戶顯示友好的頁(yè)面。所以,此處的錯(cuò)誤顯示有所不同,下面區(qū)分說(shuō)明之。
當(dāng)處于調(diào)試模式時(shí),將直接渲染exception視圖展示錯(cuò)誤。將按以下路徑搜索:

  • protected/views/system/exception.php
  • YII_PATH/views/exception.php

顯然,默認(rèn)情況下并沒(méi)有在應(yīng)用程序中定義views/system目錄,故會(huì)使用系統(tǒng)框架自帶的視圖文件。最終包含的文件將是Yii框架中的views/exception.php。

從以上分析中可以得知,在調(diào)試模式下如果我們要使用自定義異常頁(yè)面(一般這么做的意義可能不大),則需要配置文件protected/views/system/exception.php, 可使用的變量即$data。
當(dāng)處于非調(diào)試模式下時(shí),會(huì)作如下處理:

配置文件中若為errorHandler組件定義了errorAction路由信息,則直接運(yùn)行之,否則執(zhí)行第2步流程。
嘗試加載error視圖,按以下路徑搜索(第一個(gè)搜索到的文件將被使用)

  • protected/views/system/zh_cn/error500.php
  • protected/views/system/error500.php
  • protected/views/system/zh_cn/error.php
  • protected/views/system/error.php
  • YII_PATH/views/zh_cn/error500.php
  • YII_PATH/views/error500.php
  • YII_PATH/views/zh_cn/error.php
  • Y II_PATH/views/error.php

異常的處理根據(jù)前面的分析,異常的處理機(jī)制與錯(cuò)誤處理機(jī)制類似,也會(huì)記錄日志,級(jí)別是error, 分類為"exception.$EXCEPTIONCLASS", 若是CHttpException類異常,分類名稱則為exception.CHttpException.$STATUS_CODE。如數(shù)據(jù)的異常分類稱為exception.CDbException。

接下來(lái)將錯(cuò)誤事件CExceptionEvent交由errorHandler處理,所有錯(cuò)誤信息都由CExceptionEvent對(duì)象傳遞而來(lái)。處理方法如下:

如果是調(diào)試模式,則按以下順序搜索視圖文件,第一個(gè)搜索到的文件將被使用

  • protected/views/system/exception.php
  • YII_PATH/views/exception.php

如果是非調(diào)試模式,并在配置文件中為errorHandler組件定義了errorAction屬性路由,則運(yùn)行之,否則進(jìn)入第3步。
按以下順序嘗試加載視圖文件,第一個(gè)搜索到的文件將被使用
protected/views/system/zh_cn/error500.phpprotected/views/system/error500.phpprotected/views/system/zh_cn/error.phpprotected/views/system/error.phpYII_PATH/views/zh_cn/error500.phpYII_PATH/views/error500.phpYII_PATH/views/zh_cn/error.phpY II_PATH/views/error.php

使用流程圖描述,會(huì)更清楚一些:搜尋視圖文件流程比較重要,因?yàn)樗P(guān)系到我們?nèi)绾巫远x錯(cuò)誤頁(yè)面的細(xì)節(jié)問(wèn)題,后續(xù)的流程圖詳細(xì)描述其過(guò)程。

2016317155836430.jpg (825×596)

從圖中可以看出,最容易的方式還是給errorHandler組件設(shè)置errorAction屬性指定錯(cuò)誤發(fā)生的路由

2016317155904155.jpg (804×339)

一般而言,我們最關(guān)心的是生產(chǎn)模式下錯(cuò)誤頁(yè)面的顯示問(wèn)題,經(jīng)過(guò)以上分析,有兩種方法可用:

配置文件中為errorHandler組件定義errorAction路由屬性(應(yīng)該優(yōu)先使用這個(gè)方式,以達(dá)到靈活配置目的)
定義以下文件中的任意一個(gè),實(shí)現(xiàn)自定義錯(cuò)誤頁(yè)(不推薦)

  • Protected/views/system/zh_cn/error500.php
  • protected/views/system/error500.php
  • protected/views/system/zh_cn/error.php
  • protected/views/system/error.php

第1種方式靈活可控,可以在控制器中指定視圖文件,靈活可控。

使用錯(cuò)誤處理器示例

yii\web\ErrorHandler 注冊(cè)成一個(gè)名稱為errorHandler應(yīng)用組件, 可以在應(yīng)用配置中配置它類似如下:

return [
  'components' => [
    'errorHandler' => [
      'maxSourceLines' => 20,
    ],
  ],
];

使用如上代碼,異常頁(yè)面最多顯示20條源代碼。

如前所述,錯(cuò)誤處理器將所有非致命PHP錯(cuò)誤轉(zhuǎn)換成可獲取異常,也就是說(shuō)可以使用如下代碼處理PHP錯(cuò)誤:

use Yii;
use yii\base\ErrorException;

try {
  10/0;
} catch (ErrorException $e) {
  Yii::warning("Division by zero.");
}

// execution continues...

如果你想顯示一個(gè)錯(cuò)誤頁(yè)面告訴用戶請(qǐng)求是無(wú)效的或無(wú)法處理的,可簡(jiǎn)單地拋出一個(gè) yii\web\HttpException異常, 如 yii\web\NotFoundHttpException。錯(cuò)誤處理器會(huì)正確地設(shè)置響應(yīng)的HTTP狀態(tài)碼并使用合適的錯(cuò)誤視圖頁(yè)面來(lái)顯示錯(cuò)誤信息。

use yii\web\NotFoundHttpException;

throw new NotFoundHttpException();

自定義錯(cuò)誤顯示

yii\web\ErrorHandler錯(cuò)誤處理器根據(jù)常量YII_DEBUG的值來(lái)調(diào)整錯(cuò)誤顯示, 當(dāng)YII_DEBUG 為 true (表示在調(diào)試模式),錯(cuò)誤處理器會(huì)顯示異常以及詳細(xì)的函數(shù)調(diào)用棧和源代碼行數(shù)來(lái)幫助調(diào)試, 當(dāng)YII_DEBUG 為 false,只有錯(cuò)誤信息會(huì)被顯示以防止應(yīng)用的敏感信息泄漏。

補(bǔ)充: 如果異常是繼承 yii\base\UserException,不管YII_DEBUG為何值,函數(shù)調(diào)用棧信息都不會(huì)顯示, 這是因?yàn)檫@種錯(cuò)誤會(huì)被認(rèn)為是用戶產(chǎn)生的錯(cuò)誤,開發(fā)人員不需要去修正。
yii\web\ErrorHandler 錯(cuò)誤處理器默認(rèn)使用兩個(gè)視圖顯示錯(cuò)誤:

  • @yii/views/errorHandler/error.php: 顯示不包含函數(shù)調(diào)用棧信息的錯(cuò)誤信息是使用, 當(dāng)YII_DEBUG 為 false時(shí),所有錯(cuò)誤都使用該視圖。
  • @yii/views/errorHandler/exception.php: 顯示包含函數(shù)調(diào)用棧信息的錯(cuò)誤信息時(shí)使用。

可以配置錯(cuò)誤處理器的 yii\web\ErrorHandler::errorView 和 yii\web\ErrorHandler::exceptionView 屬性 使用自定義的錯(cuò)誤顯示視圖。

使用錯(cuò)誤操作

使用指定的錯(cuò)誤操作 來(lái)自定義錯(cuò)誤顯示更方便, 為此,首先配置errorHandler組件的 yii\web\ErrorHandler::errorAction 屬性,類似如下:

return [
  'components' => [
    'errorHandler' => [
      'errorAction' => 'site/error',
    ],
  ]
];

yii\web\ErrorHandler::errorAction 屬性使用路由到一個(gè)操作, 上述配置表示不用顯示函數(shù)調(diào)用棧信息的錯(cuò)誤會(huì)通過(guò)執(zhí)行site/error操作來(lái)顯示。

可以創(chuàng)建site/error 操作如下所示:

namespace app\controllers;

use Yii;
use yii\web\Controller;

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

上述代碼定義error 操作使用yii\web\ErrorAction 類,該類渲染名為error視圖來(lái)顯示錯(cuò)誤。

除了使用yii\web\ErrorAction, 可定義error 操作使用類似如下的操作方法:

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

現(xiàn)在應(yīng)創(chuàng)建一個(gè)視圖文件為views/site/error.php,在該視圖文件中,如果錯(cuò)誤操作定義為yii\web\ErrorAction, 可以訪問(wèn)該操作中定義的如下變量:

  • name: 錯(cuò)誤名稱
  • message: 錯(cuò)誤信息
  • exception: 更多詳細(xì)信息的異常對(duì)象,如HTTP 狀態(tài)碼,錯(cuò)誤碼,錯(cuò)誤調(diào)用棧等。

補(bǔ)充: 如果你使用 基礎(chǔ)應(yīng)用模板 或 高級(jí)應(yīng)用模板, 錯(cuò)誤操作和錯(cuò)誤視圖已經(jīng)定義好了。

自定義錯(cuò)誤格式

錯(cuò)誤處理器根據(jù)響應(yīng)設(shè)置的格式來(lái)顯示錯(cuò)誤, 如果yii\web\Response::format 響應(yīng)格式為html, 會(huì)使用錯(cuò)誤或異常視圖來(lái)顯示錯(cuò)誤信息,如上一小節(jié)所述。 對(duì)于其他的響應(yīng)格式,錯(cuò)誤處理器會(huì)錯(cuò)誤信息作為數(shù)組賦值給yii\web\Response::data屬性,然后轉(zhuǎn)換到對(duì)應(yīng)的格式, 例如,如果響應(yīng)格式為json,可以看到如下響應(yīng)信息:

HTTP/1.1 404 Not Found
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8

{
  "name": "Not Found Exception",
  "message": "The requested resource was not found.",
  "code": 0,
  "status": 404
}

可在應(yīng)用配置中響應(yīng)response組件的beforeSend事件來(lái)自定義錯(cuò)誤響應(yīng)格式。

return [
  // ...
  'components' => [
    'response' => [
      'class' => 'yii\web\Response',
      'on beforeSend' => function ($event) {
        $response = $event->sender;
        if ($response->data !== null) {
          $response->data = [
            'success' => $response->isSuccessful,
            'data' => $response->data,
          ];
          $response->statusCode = 200;
        }
      },
    ],
  ],
];

上述代碼會(huì)重新格式化錯(cuò)誤響應(yīng),類似如下:

HTTP/1.1 200 OK
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8

{
  "success": false,
  "data": {
    "name": "Not Found Exception",
    "message": "The requested resource was not found.",
    "code": 0,
    "status": 404
  }
}

相關(guān)文章

最新評(píng)論