1. 程式人生 > >PHP 錯誤與異常處理(一)

PHP 錯誤與異常處理(一)

timg_3_

PHP 錯誤與異常處理(一)

異常與錯誤

  • PHP中的錯誤:

    
    php中大部分情況是由錯誤的語法,伺服器環境導致,使得編譯器無法通過檢查,甚至無法執行的情況。warning、notice都是錯誤,只是他們的級別不同而已,並且錯誤是不能被try-catch捕獲的。
    
  • PHP中的異常:

    程式在執行中出現不符合預期的情況,允許發生(你也不想讓他出現不正常的情況)但他是一種不正常的情況,按照我們的正常邏輯本不該出的錯誤,但仍然會出現的錯誤,屬於邏輯和業務流程的錯誤,而不是編譯或者語法上的錯誤。這種我們把他稱為異常。
    

以上是PHP中錯誤和異常的一個概念,PHP中任何自身的錯誤或者是非正常的程式碼都會當做錯誤對待,並不會以異常的形式丟擲,但是也有一些情況會當做異常和錯誤同時丟擲。也就是說,你想在資料庫連線失敗的時候自動捕獲異常是行不通的,因為這就不是異常,是錯誤。

  • 錯誤等級

要做錯誤處理,必須得明細錯誤級別:

Fatal Error:致命錯誤(指令碼終止執行)
        E_ERROR         // 致命的執行錯誤,錯誤無法恢復,暫停執行指令碼
        E_CORE_ERROR    // PHP啟動時初始化過程中的致命錯誤
        E_COMPILE_ERROR // 編譯時致命性錯,就像由Zend指令碼引擎生成了一個E_ERROR
        E_USER_ERROR    // 自定義錯誤訊息。像用PHP函式trigger_error(錯誤型別設定為:E_USER_ERROR)

    Parse Error:編譯時解析錯誤,語法錯誤(指令碼終止執行)
        E_PARSE  //編譯時的語法解析錯誤

    Warning Error:警告錯誤(僅給出提示資訊,指令碼不終止執行)
        E_WARNING         // 執行時警告 (非致命錯誤)。
        E_CORE_WARNING    // PHP初始化啟動過程中發生的警告 (非致命錯誤) 。
        E_COMPILE_WARNING // 編譯警告
        E_USER_WARNING    // 使用者產生的警告資訊

    Notice Error:通知錯誤(僅給出通知資訊,指令碼不終止執行)
        E_NOTICE      // 執行時通知。表示指令碼遇到可能會表現為錯誤的情況.
        E_USER_NOTICE // 使用者產生的通知資訊。

由此可知有5類是產生ERROR級別的錯誤,這種錯誤直接導致PHP程式退出。

  • 簡單的錯誤處理:

PHP程式碼在執行的過程中,一旦出現錯誤,就會觸發系統的錯誤處理機制。如果我們配置了錯誤報告就回直接報告出錯誤。如圖所示:

像這樣的處理如果我們的程式碼在生產上執行,就會暴露很多資訊(比如伺服器的系統),所以我們會做簡單的配置:

第一種: 修改php.ini 配置檔案:

error_reporting = E_ALL //將向PHP傳送每個錯誤
display_errors = Off //不顯示錯誤報告
log_errors = On   //開啟錯誤日誌記錄
log_errors_max_log = 1024 //每條日誌的最大長度
error_log = G:/myerror.log //指定錯誤日誌檔案

注意:由於我們關閉了錯誤報告,但是錯誤是存在的,為了排查錯誤,我們開啟了錯誤日誌.

第二種: 不修改配置檔案,在程式碼層處理

error_reporting(E_ALL);  //將向PHP傳送每個錯誤
ini_set('display_errors',0); //不顯示錯誤報告
ini_set('log_errors',1);    //開啟錯誤日誌記錄
ini_set('error_log','./error.log'); //指定錯誤日誌檔案
test();

執行以上程式碼,就會發現 當前目錄下出現 error.log 的檔案,內容如下:

[05-Jul-2018 03:37:38 UTC] PHP Fatal error:  Uncaught Error: Call to undefined function test() in D:\phpStudy\WWW\test.php:6
Stack trace:
#0 {main}
  thrown in D:\phpStudy\WWW\test.php on line 6
  • 簡單的PHP異常處理
function checkNum($number)
{
 return 100/$number;
}

如上程式碼所示: 在呼叫 checkNum()函式的時候 如果在呼叫的時候 引數傳遞為0,就會出現異常,這個時候我們就會用到 異常處理操作:

function checkNum($number)
{
    if($number==0) {
        throw new Exception("引數不能為0");
    }
    return 100/$number;
}

然後在呼叫的時候:

<?php
try {
    checkNum(2);
    echo '成功了';
} //捕獲異常
catch (Exception $e) {
    echo '錯誤資訊: ' . $e->getMessage();
}

再比如如下的異常處理:

<?php
$pdo = new PDO('mysql://host=wrong_host;dbname=wrong_name');
$count = $pdo->exec("DELETE FROM fruit WHERE colour = 'red'");

我們連結資料庫執行刪除操作的時候,我們無法確保資料庫的地址和使用者名稱輸入都是正確的時候,就會使用異常處理操作,來優化我們的程式碼

try {
    $pdo = new PDO('mysql://host=wrong_host;dbname=wrong_name');
    $count = $pdo->exec("DELETE FROM fruit WHERE colour = 'red'");
} catch (PDOException $e) {
    $code = $e->getCode();
    $message = $e->getMessage();
    echo '對不起,業務正忙,請稍後再試';
    exit;
}

Exception是所有異常的基類。他提供了一下方法給我們用來處理異常:

Exception::getMessage — 獲取異常訊息內容
Exception::getPrevious — 返回異常鏈中的前一個異常
Exception::getCode — 獲取異常程式碼
Exception::getFile — 建立異常時的程式檔名稱
Exception::getLine — 獲取建立的異常所在檔案中的行號
Exception::getTrace — 獲取異常追蹤資訊
Exception::getTraceAsString — 獲取字串型別的異常追蹤資訊
Exception::__toString — 將異常物件轉換為字串
Exception::__clone — 異常克隆

原文連結:

PHP 錯誤與異常處理(一)