這篇文章介紹的內容是關於PHP7錯誤異常級別,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下
探究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。
為了聯合這兩個例外分支,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();
在 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 實例。
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
included/required 文件,或eval() 中的程式碼包含語法錯誤時,ParseError 將會被拋出。
try { require 'file-with-parse-error.php'; } catch (ParseError $e) { echo $e->getMessage(), "\n"; }
拋出ArithmeticError 錯誤有兩種情況:負數位移,或使用PHP_INT_MIN 當作分子,-1 做分母呼叫intp()(PHP_INI_MIN / -1傳回值是浮點型)。
try { $value = 1 << -1; } catch (ArithmeticError $e) { echo $e->getMessage(), "\n"; }
分母為零時使用 intp() 或取餘(%) 會拋出 pisionByZeroError 錯誤。注意,除零只會引起一個警告,計算結果為 NaN。
try { $value = 1 % 0; } catch (pisionByZeroError $e) { echo $e->getMessage(), "\n"; }
當不滿足 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 基类的拓展。这可能带来重要的问题:什么场合下应该抛出一个 Exception 类的子类实例,什么场合下又应该抛出 Error 类的子类实例?
由于错误对象不应当在程序运行中处理,捕获错误对象应当是少见的。通常而言,错误对象应当捕获并记录之,执行必要的清理,并给用户展示错误信息。
在 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
相关推荐:
以上是PHP 7 錯誤異常級別的詳細內容。更多資訊請關注PHP中文網其他相關文章!