PHP 錯誤與異常處理(一)
阿新 • • 發佈:2018-12-04
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 — 異常克隆
原文連結: