PHP 7 錯誤異常層級

來源:互聯網
上載者:User

這篇文章介紹的內容是關於PHP7錯誤異常層級,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

PHP 7 錯誤異常層級


探究 PHP 7 的異常階層

在過去的 PHP 中,幾乎不可能會去處理致命錯誤。致命錯誤只會輕易的終止指令碼執行,而不會調用 set_error_hander() 錯誤處理程式。

在 PHP 7 中,當致命或是可恢複性錯誤 (E_ERROR and E_RECOVERABLE_ERROR) 發生時,異常會被捕獲,而不是中止指令碼。在特定的情況下,還是存在會致命的錯誤,比如記憶體不足之類,也會像之前一樣立即中止指令碼。PHP 7 中未捕獲的異常依舊時致命錯誤。這意味著,如果 PHP 5.x 中未捕獲的異常,在 PHP 7 中依舊是致命錯誤。

注意,例如警告或是通知錯誤在 PHP 7 中保持不變,只有致命錯誤或是可恢複性錯誤會拋出異常。

致命或是可恢複性錯誤的拋出並不延伸自 Exception 類。這種分離是為了防止現存的 PHP 5.x 代碼接收到的錯誤異常調用到終止程式。致命或是可恢複錯誤拋出的異常將執行個體化一個新的異常類:Error。和其他異常類相同,被捕獲到的 Error 類將會在最後一個程式塊執行完畢之後再行處理。

相較於 PHP 7 alpha-2 之前,PHP 7 的異常類層次有所不同, 被拋出的致命和可恢複性的錯誤將於 EngineException 類執行個體化,而 EnginException 類並不繼承於 Exception。Exception 和 EngineException 都繼承於 BaseException。

Throwable

為了聯合這兩個異常分支,Exception 和 Error 都實現了一個新的介面,Throwable。

PHP 7 中新的異常層次如下:

Throwable //(介面)    |- Exception implements Throwable        |- ...    |- Error implements Throwable        |- TypeError extends Error         |- ParseError extends Error // 編譯時間錯誤        |- ArithmeticError extends Error            |- pisionByZeroError extends ArithmeticError        |- AssertionError extends Error

如果在 PHP 7 中定義 Throwable 介面,那應該和下面的代碼相近。

interface Throwable{    public function getMessage(): string;    public function getCode(): int;    public function getFile(): string;    public function getLine(): int;    public function getTrace(): array;    public function getTraceAsString(): string;    public function getPrevious(): Throwable;    public function __toString(): string;}

這個介面應當很熟悉。Throwable 特定的方法和 Exception 的相同。唯一不同的是 Throwable::getPrevious() 會返回 Throwable Exception 和 Error 類的建構函式都將接收一個 Throwable 的執行個體作為先前的異常。

Throwable 可以在 try/catch 塊中用老捕獲異常或是錯誤對象(將來可能可以捕獲更多的異常類型)。記住,這裡更建議捕獲更為具體的異常類,並採取相應的處理措施。然而,在一些場合下,需要寬泛的捕獲異常(比如日誌或是架構的錯誤處理)。在 PHP 7 中,這些異常捕獲塊更適合使用 Throwable 而不是 Exception。

try {    // Code that may throw an Exception or Error.} catch (Throwable $t) {    // Handle exception}

自訂類不能實現 Throwable 外掛程式,這個部分由於可預見性和一致性:只有執行個體化 Excetion 和 Error 類才能拋出異常。此外,異常攜帶了棧中被建立的對象的資訊。自訂類並未自動擁有儲存資訊的參數。

Throwable can be extended to create package-specific interfaces or add additional methods. 只有繼承了 Exception 或是 Error 的類才可以實現拓展了 Throwable 的外掛程式。

interface MyPackageThrowable extends Throwable {}class MyPackageException extends Exception implements MyPackageThrowable {}throw new MyPackageException();

Error

在 PHP 5.下版本中所有的 errors 都是致命錯誤或是可恢複性致命錯誤,而在 PHP 7 中都拋出 Error 的執行個體化。像其他異常 Error 對象可以通過 try/catch 程式塊捕獲。

$var = 1;try {    $var->method(); // Throws an Error object in PHP 7.} catch (Error $e) {    // Handle error}

通常,之前的致命錯誤都將拋出 Error 基類的執行個體化,但是一些錯誤會拋出更加確切的 Error 子類:TypeError, ParseError, and AssertionError。

TypeError (類型錯誤)

TypeError 執行個體化的拋出是由實參和形參 當調用函數時申明的形參和實參類型不一致(傳入參數和方法中定義的參數類型不一致)將會拋出一個 TypeError 執行個體。

function add(int $left, int $right){    return $left + $right;}try {    $value = add('left', 'right');} catch (TypeError $e) {    echo $e->getMessage(), "\n";}

得到的輸出:

Argument 1 passed to add() must be of the type integer, string given

ParseError (解析錯誤)

included/required 檔案,或者 eval() 中的程式碼封裝含語法錯誤時,ParseError 將會被拋出。

try {    require 'file-with-parse-error.php';} catch (ParseError $e) {    echo $e->getMessage(), "\n";}

ArithmeticError (算數錯誤)

拋出 ArithmeticError 錯誤有兩種情況:負數位移,或者使用 PHP_INT_MIN 當作分子,-1 做分母調用 intp()(PHP_INI_MIN / -1 傳回值是浮點型)。

try {    $value = 1 << -1;} catch (ArithmeticError $e) {    echo $e->getMessage(), "\n";}

pisionByZeroError (分母為零)

分母為零時使用 intp() 或者取餘(%) 會拋出 pisionByZeroError 錯誤。注意,除零隻會引起一個警告,計算結果為 NaN。

try {    $value = 1 % 0;} catch (pisionByZeroError $e) {    echo $e->getMessage(), "\n";}

AssertionError (斷言)

當不滿足 assert() 設定的條件時,將會拋出一個 AssertionError 錯誤。

ini_set('zend.assertions', 1);ini_set('assert.exception', 1);$test = 1;assert($test === 0);

不滿足 assert() 設定的條件,拋出一個 AssertionError 錯誤,並且 assert.exception = 1,異常輸出如下:

Fatal error: Uncaught AssertionError: assert($test === 0)

assert() is only executed and will only throw an AssertionError if assertions are enabled and set to throw exceptions with ini settings zend.assertions = 1 and assert.exception = 1.

使用 Error

使用者可以建立自己的 Error 類,作為 Error 基類的拓展。這可能帶來重要的問題:什麼場合下應該拋出一個 Exception 類的子類執行個體,什麼場合下又應該拋出 Error 類的子類執行個體?

由於錯誤對象不應當在程式運行中處理,捕獲錯誤對象應當是少見的。通常而言,錯誤對象應當捕獲並記錄之,執行必要的清理,並給使用者展示錯誤資訊。

編寫相容 PHP 5.x 和 7 Exceptions 類的代碼

在 PHP 5.x 和 7 使用相同的代碼捕獲異常,可以實用多重捕獲代碼塊,首先捕獲 Throwable,之後時 Exception。一旦不需要維護 PHP 5.x 的系統,代碼塊可以立刻被清理掉。

try {    // Code that may throw an Exception or Error.} catch (Throwable $t) {    // Executed only in PHP 7, will not match in PHP 5.x} catch (Exception $e) {    // Executed only in PHP 5.x, will not be reached in PHP 7}

英文原文: trowski.com/2015

本文雖拙,卻也系作者勞動,轉載還請保留本文連結: http://cyleft.com/?p=721

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.