亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

文字

在許多「重異?!?exception-heavy) 的編程語言中,一旦發(fā)生錯誤,就會拋出異常。這確實是一個可行的方式。不過 PHP 卻是一個 「輕異常」(exception-light) 的語言。當(dāng)然它確實有異常機制,在處理對象時,核心也開始采用這個機制來處理,只是 PHP 會盡可能的執(zhí)行而無視發(fā)生的事情,除非是一個嚴(yán)重錯誤。

舉例來說:

$ php -a php > echo $foo; Notice: Undefined variable: foo in php shell code on line 1

這里只是一個 notice 級別的錯誤,PHP 仍然會愉快的繼續(xù)執(zhí)行。這對有「重異?!咕幊探?jīng)驗的人來說會帶來困惑,例如在 Python 中,引用一個不存在的變量會拋出異常:

$ python >>> print foo Traceback (most recent call last):   File "<stdin>", line 1, in <module> NameError: name 'foo' is not defined

本質(zhì)上的差異在于 Python 會對任何小錯誤進行拋錯,因此開發(fā)人員可以確信任何潛在的問題或者邊緣的案例都可以被捕捉到,與此同時 PHP 仍然會保持執(zhí)行,除非極端的問題發(fā)生才會拋出異常。

錯誤嚴(yán)重性

PHP 有幾個錯誤嚴(yán)重性等級。三個最常見的的信息類型是錯誤(error)、通知(notice)和警告(warning)。它們有不同的嚴(yán)重性: E_ERROR 、E_NOTICE和 E_WARNING。錯誤是運行期間的嚴(yán)重問題,通常是因為代碼出錯而造成,必須要修正它,否則會使 PHP 停止執(zhí)行。通知是建議性質(zhì)的信息,是因為程序代碼在執(zhí)行期有可能造成問題,但程序不會停止。 警告是非致命錯誤,程序執(zhí)行也不會因此而中止。

另一個在編譯期間會報錯的信息類型是「E_STRICT」。這個信息用來建議修改程序代碼以維持最佳的互通性并能與今后的 PHP 版本兼容。

更改 PHP 錯誤報告行為

錯誤報告可以由 PHP 配置及函數(shù)調(diào)用改變。使用 PHP 內(nèi)置的函數(shù) error_reporting(),可以設(shè)定程序執(zhí)行期間的錯誤等級,方法是傳入預(yù)定義的錯誤等級常量,這意味著如果你只想看到警告和錯誤 - 而非通知 - 你可以這樣設(shè)定:

<?php error_reporting(E_ERROR | E_WARNING);

你也可以控制錯誤是否在屏幕上顯示 (開發(fā)時比較有用)或隱藏后記錄日志 (適用于正式環(huán)境)。如果想知道更多細(xì)節(jié),可以查看 錯誤報告 章節(jié)。

行內(nèi)錯誤抑制

你可以讓 PHP 利用錯誤控制操作符 @ 來抑制特定的錯誤。將這個操作符放置在表達式之前,其后的任何錯誤都不會出現(xiàn)。

<?php echo @$foo['bar'];

如果 $foo['bar'] 存在,程序會將結(jié)果輸出,如果變量 $foo 或是 'bar' 鍵值不存在,則會返回 null 并且不輸出任何東西。如果不使用錯誤控制操作符,這個表達式會產(chǎn)生一個錯誤信息 PHP Notice: Undefined variable: foo 或 PHP Notice: Undefined index: bar 。

這看起來像是個好主意,不過也有一些討厭的代價。PHP 處理使用 @ 的表達式比起不用時效率會低一些。過早的性能優(yōu)化在所有程序語言中也許都是爭論點,不過如果性能在你的應(yīng)用程序 / 類庫中占有重要地位,那么了解錯誤控制操作符的性能影響就比較重要。

其次,錯誤控制操作符會 完全 吃掉錯誤。不但沒有顯示,而且也不會記錄在錯誤日志中。此外,在正式環(huán)境中 PHP 也沒有辦法關(guān)閉錯誤控制操作符。也許你認(rèn)為那些錯誤時無害的,不過那些較具傷害性的錯誤同時也會被隱藏。

如果有方法可以避免錯誤抑制符,你應(yīng)該考慮使用,舉例來說,上面的程序代碼可以這樣重寫:

<?php echo isset($foo['bar']) ? $foo['bar'] : '';

當(dāng) fopen() 載入文件失敗時,也許是一個使用錯誤抑制符的合理例子。你可以在嘗試載入文件前檢查是否存在,但是如果這個文件在檢查后才被刪除,而此時 fopen() 還未執(zhí)行 (聽起來有點不太可能,但是確實會發(fā)生),這時 fopen()會返回 false 并且 拋出操作。這也許應(yīng)該由 PHP 本身來解決,但這時一個錯誤抑制符才能有效解決的例子。

前面我們提到在正式的 PHP 環(huán)境中沒有辦法關(guān)閉錯誤控制操作符。但是 Xdebug 有一個 xdebug.scream 的 ini 配置項,可以關(guān)閉錯誤控制操作符。你可以按照下面的方式修改 php.ini。

xdebug.scream = On

你也可以在執(zhí)行期間通過 ini_set 函數(shù)來設(shè)置這個值:

<?php ini_set('xdebug.scream', '1')

「Scream」這個 PHP 擴展提供了和 xDebug 類似的功能,只是 Scream 的 ini 設(shè)置項叫做 scream.enabled 。

當(dāng)你在調(diào)試代碼而錯誤信息被隱藏時,這是最有用的方法。請務(wù)必小心使用 scream ,而是把它當(dāng)作暫時性的調(diào)試工具。有許多的 PHP 函數(shù)類庫代碼也許無法在錯誤抑制操作符停用時正常使用。

Error Control Operators

SitePoint

Xdebug

Scream

錯誤異常類

PHP 可以完美化身為「重異常」的程序語言,只需要幾行代碼就能切換過去。基本上你可以利用 ErrorException 類拋出「錯誤」來當(dāng)做「異?!梗@個類是繼承自 Exception 類。

這在大量的現(xiàn)代框架中是一個常見的做法,比如 Symfony 和 Laravel。在調(diào)試(debug)模式 (或叫開發(fā)模式) 下,這些框架都能夠展示一份簡潔干凈的 stack trace。

還有一些對錯誤(error)和異常(exception)的處理更加優(yōu)秀的包(package),例如 Whoops!,它在 Laravel 中是默認(rèn)安裝的并且也可以被用在任意框架中。

在開發(fā)過程中將錯誤當(dāng)作異常拋出可以更好的處理它,如果在開發(fā)時發(fā)生異常,你可以將它包在一個 catch 語句中具體說明這種情況如何處理。每捕捉一個異常,都會使你的應(yīng)用程序越來越健壯。


上一篇: 下一篇: