首頁 >後端開發 >php教程 >PHP 核心特性 - 錯誤處理

PHP 核心特性 - 錯誤處理

PHPz
PHPz轉載
2016-07-28 08:30:171175瀏覽

錯誤與異常

錯誤,可以理解程式本身的錯誤,例如語法錯誤。而異常則更偏向程式運行不符合預期或不符合正常流程;對於 PHP 語言而言,處理錯誤和處理異常使用的機製完全不同,因此很容易讓人困惑。

例如,我們希望透過捕獲異常來處理除數為 0 的情況,但是在捕獲到異常之前,PHP 就觸發了錯誤。

try {
    $a = 5 / 0;
} catch (Exception $e) {
    $e->getMessage();
    $a = -1;  // 通过异常来处理 $a 为 0 的情况,但是实际上,捕获不到该异常
}
echo $a;
// PHP Warning:  Division by zero

也就是說,PHP 將除數為 0 的情況當成了錯誤而觸發,而不會自動拋出異常,因此沒法捕獲。類似的,在許多情況下,PHP 都沒辦法自動拋出異常。只能透過 if - else 語句判斷再結合 throw 方法來並手動拋出異常。

上述情況的發生,主要還是因為異常機制是 PHP 向物件導向演進後所得到的產物。而在此之前 PHP 的報錯主要還是透過錯誤機制,因此,在許多情況下,PHP 的錯誤要比異常更有價值。不過 PHP7 開始統一這兩者,讓錯誤也可以像異常一樣拋出(這部分內容將放在異常部分講解)。

錯誤等級

PHP 中的錯誤可理解為腳本不運作不正常的情況,根據錯誤等級從高到低可分為五類別

● Parse error 或Syntax Error - 語法解析錯誤,觸發該錯誤後,腳本完全無法運行;
● Fatal Error - 致命錯誤,觸發該錯誤後,後面的腳本無法繼續執行;
●Warning Error - 出現比較不恰當的地方,腳本可繼續執行;
●Notice Error - 出現不恰當的地方,但是程度比Warning Error 低,腳本可繼續執行;
●Deprecated Error● - 不建議這麼使用,未來可能會廢棄,腳本可繼續執行;

預設情況下,PHP 觸發錯誤,並顯示錯誤的等級及對應的提示。

Parse Error 範例- 語句結尾不寫分號
echo "abc"
// PHP Parse error:  syntax error, unexpected end of file, expecting ',' orntax '
Fatal Error 範例- 使用不存在的函數
echo "beforen";
foo();
echo "after"; // 本行無法繼續執行
// before
// PHP Fatal error:  Uncaught Error: Call to undefined function foo()
Warning Error 範例- 引入不存在的檔案
$a = "foo";
include('bar.php') ;
echo $a; // 程式繼續執行
// PHP Warning:  include(bar.php): failed to open stream: No such file or directory ...
// foo
Notice Error 範例- 輸出不存在的變數
echo $foo;
echo 12345;
// PHP Notice:  Undefined variable: foo
// 12345 precated Error 在一些例子串函數中傳入數字而非字串
strpos('12345', 3);
// PHP Deprecated:  strpos(): Non-string needles will be interpreted as strings in the future

除了預設觸發訊息外,使用者也可以使用 set_error_handler 函數自訂錯誤處理,大多數錯誤類型都可以進行自訂處理,除了 E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPILE_WARNING 外。

set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] ) : mixed
範例


<?php
// E_ALL - 处理全部错误类型
set_error_handler(&#39;customError&#39;, E_ALL);
/**
 * @param  int $errno 错误的级别
 * @param  string $errstr  错误的信息
 * @param  string $errfile 错误的文件名(可选)
 * @param  string $errline 错误发生的行号(可选)
 */
function customError(int $errno, string $errstr, string $errfile, string $errline)
{
    echo sprintf(&#39;错误消息为 %s&#39;, $errstr);
}
$a = 5 / 0;  // 错误消息为 Division by zero
範例


function division($a, $b) {
    if($b == 0){
        @trigger_error("0 不能作为除数", E_USER_NOTICE);
        return -1;
    }
    return $a / $b;
}
echo division(10, 0);
使用者也可以透過 trigger_error 函數來手動觸發一個使用者層級的錯誤(E_USER_ERROR、E_USER_WARNING、EICEAERNING、E_USER_NOD、RICE_USD)。


與錯誤相關的設定




一些錯誤處理相關的常用設定
● 設定錯誤的報告等級

● display_errors - 是否顯示錯誤

● display_startup_error - 是否顯示PHP 啟動過程中的顯示● log_errors - 設定是否將腳本執行的錯誤訊息記錄到伺服器錯誤日誌或error_log 之中


《Modern PHP》提出了四個規則

● 一定要讓PHP 報告錯誤;

● 在開發環境中要顯示錯誤;● 在生產環境中不能顯示錯誤;● 在開發環境和生產環境中都要記錄錯誤;

display_errors = On
display_startup_error = On
error_reporting = -1
log_errors = On
開發環境建議配置


display_errors = Off
display_startup_error = Off
; 报告 Notice 以外的所有错误
error_reporting = E_ALL & ~E_NOTICE
log_errors = On
生產環境建議設定


Symfony 編碼規範相關

throw new CommandNotFoundException(sprintf(&#39;Command "%s" does not exist.&#39;, $name));

異常和錯誤訊息字串必須使用sprintf 來進行拼接;

@trigger_error("foo", E_USER_DEPRECATED);
當錯誤類型為E_USER_DEPRECATED 時,需要加@
陳述:
本文轉載於:learnku.com。如有侵權,請聯絡admin@php.cn刪除