久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長(zhǎng)資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

聊聊在PHP7中對(duì)于Error的處理是怎樣的

前段時(shí)間在項(xiàng)目中遇到一個(gè)當(dāng)時(shí)覺(jué)得比較奇怪的情況:使用 GuzzleHttp 發(fā)送 curl 請(qǐng)求,API 響應(yīng)超時(shí)導(dǎo)致拋出異常。但 catch(Exception) 并沒(méi)有捕獲異常,導(dǎo)致代碼意外停止運(yùn)行。后來(lái)查資料發(fā)現(xiàn),在 PHP 7 中,GuzzleHttp 請(qǐng)求超時(shí)拋出的異常繼承的是 Error,而 Error 并沒(méi)有繼承 Exception,所以 catch(Exception) 無(wú)法捕獲并處理該異常。

PHP 7 中對(duì) Error 的處理

在 PHP 5 中,當(dāng)程序中有致命錯(cuò)誤發(fā)生時(shí),腳本會(huì)立即停止運(yùn)行。并且,通過(guò) set_error_handler 設(shè)置的錯(cuò)誤處理程序在這種情況下并不會(huì)被調(diào)用。

【推薦學(xué)習(xí):PHP7教程】

⒈ 自定義錯(cuò)誤處理程序 set_error_handler

??set_error_handler 接受兩個(gè)參數(shù),第一個(gè)為自定義的錯(cuò)誤處理函數(shù),第二個(gè)參數(shù)指定觸發(fā)該自定義錯(cuò)誤處理函數(shù)的錯(cuò)誤級(jí)別。但需要指出的是,在任何時(shí)候,只能有一個(gè)自定義的錯(cuò)誤處理程序起作用。

function func_notice($num, $str, $file, $line) {     print "Encountered notice $num in $file, line $line: $strn"; } function func_error($num, $str, $file, $line) {     print "Encountered error $num in $file, line $line: $strn"; } set_error_handler("func_notice", E_NOTICE); set_error_handler("func_error", E_ERROR); echo $foo;

??以上代碼在執(zhí)行以后,會(huì)輸出 PHP Notice: Undefined variable: foo 。在第二個(gè) set_error_handler 執(zhí)行以后,自定義錯(cuò)誤處理函數(shù)變成了 func_error ,同時(shí),觸發(fā)自定義錯(cuò)誤處理函數(shù)的錯(cuò)誤級(jí)別變成了 E_ERROR 。而在 PHP 中,變量未定義只會(huì)觸發(fā) E_NOTICE 級(jí)別的錯(cuò)誤,所以自定義的錯(cuò)誤處理函數(shù)并不會(huì)被觸發(fā)。

需要指出的是,自定義的錯(cuò)誤處理函數(shù)對(duì)以下幾種錯(cuò)誤級(jí)別并不起作用:

E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING、E_STRICT

??在上述幾種自定義錯(cuò)誤處理程序無(wú)法處理的錯(cuò)誤中,凡是以 ERROR 結(jié)尾的都是致命錯(cuò)誤。其他幾種雖然不是致命錯(cuò)誤,但

  • E_PARSE 是在解析 PHP 代碼時(shí)產(chǎn)生的錯(cuò)誤,此時(shí) PHP 代碼尚未開(kāi)始運(yùn)行,自定義錯(cuò)誤處理程序自然無(wú)法處理該錯(cuò)誤

  • E_CORE_WARNING 產(chǎn)生于 PHP 的初始化啟動(dòng)階段,此時(shí) PHP 代碼仍然尚未運(yùn)行,所以不能被自定義錯(cuò)誤處理程序處理

  • E_COMPILE_WARNING 是在 PHP 代碼的編譯階段產(chǎn)生,所以不能被自定義錯(cuò)誤處理程序處理

而至于 E_STRICT 是 PHP 為了保證代碼的最佳互操作性和向前兼容而提出的代碼修改建議,自然也不會(huì)被自定義錯(cuò)誤處理函數(shù)處理

function func_error($num, $str, $file, $line) {     print "Encountered error $num in $file, line $line: $strn"; } set_error_handler('func_error', E_NOTICE); $obj = 'foo'; $obj->method();

?? 以上代碼運(yùn)行輸出結(jié)果:

PHP Fatal error:  Call to a member function method() on string

??雖然設(shè)置了自定義錯(cuò)誤處理程序,但在致命錯(cuò)誤發(fā)生時(shí),并不起作用。

??對(duì)于這種自定義錯(cuò)誤處理程序無(wú)法處理的致命錯(cuò)誤,在 PHP 5 中可以通過(guò)注冊(cè)一個(gè)終止回調(diào)(shutdown_function)來(lái)記錄具體的錯(cuò)誤信息,但也僅限于記錄錯(cuò)誤信息,當(dāng)發(fā)生致命錯(cuò)誤時(shí)代碼仍然會(huì)停止運(yùn)行。

$shutdownHandler = function(){     print PHP_EOL;     print "============================" . PHP_EOL;     print "Running the shutdown handler" . PHP_EOL;     $error = error_get_last();     if (!empty($error))     {         print "Looks like there was an error: " . print_r($error, true) . PHP_EOL;         // 可以添加記錄日志的邏輯     }     else     {         // 程序正常運(yùn)行結(jié)束         print "Running a normal shutdown without error." . PHP_EOL;     } }; register_shutdown_function($shutdownHandler); $obj = 'foo'; $obj->method();

??以上代碼執(zhí)行會(huì)輸出

PHP Fatal error:  Call to a member function method() on string in /home/chenyan/test.php on line 24 ============================ Running the shutdown handler Looks like there was an error: Array (     [type] => 1     [message] => Call to a member function method() on string     [file] => /home/chenyan/test.php     [line] => 24 )

⒉ 撤銷自定義錯(cuò)誤處理程序

??當(dāng)同時(shí)設(shè)置多個(gè)自定義錯(cuò)誤處理程序時(shí),雖然只有最后設(shè)置的自定義錯(cuò)誤處理程序起作用。但所有設(shè)置的自定義錯(cuò)誤處理程序會(huì)以棧的方式保存(FILO)。

??使用 restore_error_handler 可以撤銷最近一次設(shè)置的自定義錯(cuò)誤處理程序;如果同時(shí)調(diào)用了多次 set_error_handler ,則每調(diào)用一次 restore_error_handler,處于棧頂?shù)腻e(cuò)誤處理程序就會(huì)被撤銷。

function func_notice($num, $str, $file, $line) {     print "Encountered notice : $strn"; } set_error_handler("func_notice", E_NOTICE); set_error_handler("func_notice", E_NOTICE); set_error_handler("func_notice", E_NOTICE); echo $foo; set_error_handler("func_notice", E_NOTICE); echo $foo; restore_error_handler(); echo $foo; restore_error_handler(); echo $foo; restore_error_handler(); echo $foo; restore_error_handler(); echo $foo;

??以上代碼運(yùn)行,會(huì)輸出:

Encountered notice : Undefined variable: foo Encountered notice : Undefined variable: foo Encountered notice : Undefined variable: foo Encountered notice : Undefined variable: foo Encountered notice : Undefined variable: foo PHP Notice:  Undefined variable: foo

⒊ PHP 7 中對(duì)錯(cuò)誤的處理

??在 PHP 7 中,當(dāng)有致命錯(cuò)誤或 E_RECOVERABLE_ERROR 類型的錯(cuò)誤發(fā)生時(shí),通常會(huì)拋出一個(gè) Error,程序并不會(huì)終止。

try {     $obj = 'foo';     $obj->method(); } catch (Error $e) {     echo $e->getMessage(); }

??運(yùn)行以上代碼會(huì)輸出

Call to a member function method() on string

E_RECOVERABLE_ERROR 是一種可捕獲的致命錯(cuò)誤,這種錯(cuò)誤的出現(xiàn)并不會(huì)使得 Zend 引擎處于不穩(wěn)定的狀態(tài),但必須被捕獲并且處理。如果不處理,那么這種錯(cuò)誤最終會(huì)變成 E_ERROR 類型的錯(cuò)誤,最終導(dǎo)致 PHP 代碼停止運(yùn)行。

??php 7 中,并不是所有的致命錯(cuò)誤都會(huì)拋出 Error,一些特定情況下出現(xiàn)的致命錯(cuò)誤( Out Of Memory)仍然會(huì)導(dǎo)致代碼停止運(yùn)行。另外,如果拋出的 Error 沒(méi)有被捕獲并處理,則代碼仍然會(huì)停止運(yùn)行。

// bak.sql 的大小為 377 M // PHP 配置的 memory_limit = 128M try {     $file = './bak.sql';     file_get_contents($file); } catch (Error $e) {     echo $e->getMessage(); } // 執(zhí)行以上代碼,仍然會(huì)產(chǎn)生致命錯(cuò)誤 PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 395191240 bytes) // 拋出的 Error 沒(méi)有被捕獲并處理,代碼依然會(huì)停止運(yùn)行 $obj = 'foo'; $obj->method(); // 執(zhí)行以上代碼,由于并沒(méi)有用 try/catch 捕獲并處理拋出的 Error,程序仍然會(huì)停止運(yùn)行 PHP Fatal error:  Uncaught Error: Call to a member function method() on string

??PHP 7 中的 Error 并沒(méi)有繼承 Exception,之所以這樣做是為了防止 PHP 5 中捕獲并處理 Exception 的代碼捕獲這些 Error。因?yàn)樵?PHP 5 中,這些致命錯(cuò)誤是會(huì)導(dǎo)致代碼停止運(yùn)行的。

??Error 和 Exception 都繼承自 Throwable 。在 PHP 7 中,Throwable 是一個(gè) interface,所有能通過(guò) throw 關(guān)鍵字拋出的對(duì)象都實(shí)現(xiàn)了這個(gè) interface。

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 是 PHP 底層的 interface,PHP 代碼中不能直接實(shí)現(xiàn) Throwable 。之所以作出這個(gè)限制,是因?yàn)橥ǔV挥?Error 和 Exception 可以被拋出,并且這些拋出的 Error 和 Exception 中還存儲(chǔ)了它們被拋出的堆棧跟蹤信息,而 PHP 代碼中開(kāi)發(fā)者自定義的 class 無(wú)法實(shí)現(xiàn)這些。

??要在 PHP 代碼中實(shí)現(xiàn) Throwable 必須通過(guò)繼承 Exception 來(lái)實(shí)現(xiàn)。

interface CustomThrowable extends Throwable {} class CustomException extends Exception implements CustomThrowable {} throw new CustomException();

??PHP 7 中 Error 和 Exception 的繼承關(guān)系

interface Throwable     |- Exception implements Throwable         |- Other Exception classes     |- Error implements Throwable         |- TypeError extends Error         |- ParseError extends Error         |- AssertionError extends Error         |- ArithmeticError extends Error             |- DivizionByZeroError extends ArithmeticError
  • TypeError

??當(dāng)函數(shù)的傳參或返回值的數(shù)據(jù)類型與申明的數(shù)據(jù)類型不一致時(shí),會(huì)拋出 TypeError

function add(int $left, int $right) {     return $left + $right; } try {     $value = add('left', 'right'); } catch (TypeError $e) {     echo $e->getMessage(); } // 運(yùn)行以上代碼,會(huì)輸出: Argument 1 passed to add() must be of the type int, string given

??當(dāng)開(kāi)啟嚴(yán)格模式時(shí),如果 PHP 內(nèi)建函數(shù)的傳參個(gè)數(shù)與要求的參數(shù)不一致,也會(huì)拋出 TypeError

declare(strict_types = 1); try {     substr('abc'); } catch (TypeError $e) {     echo $e->getMessage(); } // 運(yùn)行以上代碼,會(huì)輸出: substr() expects at least 2 parameters, 1 given

??默認(rèn)情況下,PHP 7 處于弱模式。在弱模式下,PHP 7 會(huì)盡可能的將傳參的數(shù)據(jù)類型轉(zhuǎn)換為期望的數(shù)據(jù)類型。例如,如果函數(shù)期望的參數(shù)類型為 string,而實(shí)際傳參的數(shù)據(jù)類型的 int,那么 PHP 會(huì)把 int 轉(zhuǎn)換為 string。

// declare(strict_types = 1); function add(string $left, string $right) {     return $left + $right; } try {     $value = add(11, 22);     echo $value; } catch (TypeError $e) {     echo $e->getMessage(); } // 以上代碼運(yùn)行,會(huì)正常輸出 33,PHP 會(huì)對(duì)傳參的數(shù)據(jù)類型做轉(zhuǎn)換(int→string→int) // 但如將 PHP 改為嚴(yán)格模式,則運(yùn)行是會(huì)拋出 TypeError Argument 1 passed to add() must be of the type string, int given
  • ParseError

??當(dāng)在 include 或 require 包含的文件中存在語(yǔ)法錯(cuò)誤,或 eval() 函數(shù)中的代碼中存在語(yǔ)法錯(cuò)誤時(shí),會(huì)拋出 ParseError

// a.php $a = 1 $b = 2 // test.php try {     require 'a.php'; } catch (ParseError $e) {     echo $e->getMessage(); } // 以上代碼運(yùn)行會(huì)輸出: syntax error, unexpected '$b' (T_VARIABLE) // eval 函數(shù)中的代碼存在語(yǔ)法錯(cuò)誤 try {     eval("$a = 1"); } catch (ParseError $e) {     echo $e->getMessage(); } // 以上代碼運(yùn)行會(huì)輸出: syntax error, unexpected end of file
  • AssertionError

??當(dāng)斷言失敗時(shí),會(huì)拋出 AssertionError(此時(shí)要求 PHP 配置中 zend.assertions = 1,assert.exception = 1,這兩個(gè)配置可以在 php.ini 文件中配置,也可以通過(guò) ini_set() 在 PHP 代碼中配置)。

ini_set('zend_assertions', 1); ini_set('assert.exception', 1); try {     $test = 1;     assert($test === 0); } catch (AssertionError $e) {     echo $e->getMessage(); } // 運(yùn)行以上代碼會(huì)輸出: assert($test === 0)
  • ArithmeticError

??在 PHP 7 中,目前有兩種情況會(huì)拋出 ArithmeticError:按位移動(dòng)操作,第二個(gè)參數(shù)為負(fù)數(shù);使用 intdiv() 函數(shù)計(jì)算 PHP_INT_MIN 和 -1 的商(如果使用 / 計(jì)算 PHP_INT_MIN 和 -1 的商,結(jié)果會(huì)自動(dòng)轉(zhuǎn)換為 float 類型)。

try {     $value = 1 << -1; } catch (ArithmeticError $e) {     echo $e->getMessage(); } // 運(yùn)行以上代碼,會(huì)輸出: Bit shift by negative number try {     $value = intdiv(PHP_INT_MIN, -1); } catch (ArithmeticError $e) {     echo $e->getMessage(); } // 運(yùn)行以上代碼,會(huì)輸出: Division of PHP_INT_MIN by -1 is not an integer
  • DivisionByZeroError

??拋出 DivisionByZeorError 的情況目前也有兩種:在進(jìn)行取模(%)運(yùn)算時(shí),第二個(gè)操作數(shù)為 0;使用 intdiv() 計(jì)算兩個(gè)數(shù)的商時(shí),除數(shù)為 0。如果使用 / 計(jì)算兩個(gè)數(shù)的商時(shí)除數(shù)為 0,PHP 只會(huì)產(chǎn)生一個(gè) Warning。并且,如果被除數(shù)非 0,則結(jié)果為 INF,如果被除數(shù)也是 0,則結(jié)果為 NaN。

try {     $value = 1 % 0;     echo $value; } catch (DivisionByZeroError $e) {     echo $e->getMessage(), "n"; } // 運(yùn)行以上代碼,會(huì)輸出: Modulo by zero try {     $value = intdiv(0, 0);     echo $value; } catch (DivisionByZeroError $e) {     echo $e->getMessage(), "n"; } // 運(yùn)行以上代碼,會(huì)輸出: Division by zero

??通常在實(shí)際的業(yè)務(wù)中,捕獲并處理拋出的 Error 并不常見(jiàn),因?yàn)橐坏伋?Error 說(shuō)明代碼存在嚴(yán)重的 BUG,需要修復(fù)。所以,在實(shí)際的業(yè)務(wù)中,Error

贊(0)
分享到: 更多 (0)
?
網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
国产欧美日韩| 视频在线在亚洲| 麻豆久久精品| 久久精品高清| 四虎在线精品| 精品中文字幕一区二区三区四区| 98精品久久久久久久| 国产一区二区三区国产精品| 激情综合网站| 欧美日韩在线观看视频小说| 欧美一区久久| 91精品精品| 伊人精品一区| 日韩一区电影| 韩国三级一区| 视频在线不卡免费观看| 中文字幕日本一区二区| 先锋影音国产一区| 欧美精选一区二区三区| 激情婷婷久久| 久久在线免费| 99视频精品全国免费| 米奇777超碰欧美日韩亚洲| 日韩中文欧美| 午夜国产一区二区| 免费一二一二在线视频| 久久精品国产99久久| 久久人人97超碰国产公开结果| 亲子伦视频一区二区三区| 亚洲午夜在线| 亚洲国产成人精品女人| 亚洲欧美激情诱惑| 黄色亚洲大片免费在线观看| 伊人久久在线| 午夜免费一区| 久久av一区二区三区| 日韩精品一区二区三区中文在线 | 欧美aa在线视频| 久久久久久久久成人| av高清一区| 婷婷精品进入| 日本视频一区二区| 国产劲爆久久| 日韩在线不卡| 中文无码久久精品| 欧美一区91| а√天堂8资源在线| 国产中文字幕一区二区三区| 婷婷六月综合| 日韩精品一区二区三区中文在线| 国产精久久一区二区| 日韩电影二区| 久久高清一区| 国产一区二区三区亚洲| 99久久精品国产亚洲精品| 欧美在线不卡| 国产videos久久| 日本欧美不卡| 日本欧美久久久久免费播放网| 免费在线观看一区| 香蕉成人久久| 国产欧美激情| 国产精品久久久久久久久久10秀| 一区福利视频| 日韩激情一二三区| 国产精品成人自拍| 成人在线免费观看网站| 亚洲一区二区免费看| 青青草精品视频| 精品成av人一区二区三区| 国产在线日韩| 青草国产精品| 午夜av不卡| 亚洲精品乱码日韩| 欧洲毛片在线视频免费观看| 视频一区视频二区中文| 欧美xxxx性| 三级欧美韩日大片在线看| 国产精品白丝av嫩草影院| 99xxxx成人网| 鲁大师精品99久久久| 亚洲一级二级| 欧美一级网址| 亚洲第一区色| 国产欧美日韩视频在线| 久久精品国产68国产精品亚洲| 欧美1区2区3| 美女91精品| 国产精品a级| 国产视频亚洲| 国内精品伊人| 亚洲精品日本| 欧美aa一级| 国产伦精品一区二区三区视频 | 精品日产乱码久久久久久仙踪林| 欧美精品一区二区三区精品| 国产精品麻豆成人av电影艾秋 | 鲁大师成人一区二区三区| 久久久久观看| 一区二区国产在线| 日韩中文字幕高清在线观看| 视频一区二区三区入口| 国际精品欧美精品| 国产免费av一区二区三区| 国产视频一区欧美| 亚洲第一精品影视| 国产成人精品999在线观看| 蜜臀av在线播放一区二区三区| 精品国产91| 99亚洲视频| 日韩欧美国产精品综合嫩v| 视频一区中文字幕| 国产精品毛片| 日韩大片在线| 日韩av专区| 国产精品一区二区中文字幕| 午夜一级久久| 婷婷激情久久| 欧美丰满日韩| 国产精品一级| 亚洲精品韩国| 亚洲精品1区| 99精品视频在线观看免费播放| 国产麻豆精品| 国产高清亚洲| 欧美欧美黄在线二区| 国产探花在线精品一区二区| 亚洲无线观看| 亚洲精品综合| 亚洲欧美日韩精品一区二区 | 日韩高清中文字幕一区二区| 奇米色欧美一区二区三区| 日韩国产欧美在线播放| 久久亚洲色图| 国产视频一区二区在线播放| 蜜桃视频一区二区三区| 激情婷婷久久| 日韩精品欧美| 国产亚洲一区| jiujiure精品视频播放| 久久精品九色| 欧美视频久久| 日韩一区二区三区在线看| 视频在线观看国产精品| 日韩国产一区二区三区| а√天堂8资源中文在线| 国产精品1区| 国产精品视频一区二区三区 | 午夜久久一区| 亚洲网址在线观看| 蜜臀av在线播放一区二区三区 | 国产精品成久久久久| 日韩一区电影| 日韩欧美综合| 伊人精品视频| 天堂av在线一区| 日韩av自拍| 精品五月天堂| 久久国产免费看| 欧美综合社区国产| 91欧美极品| 欧美激情99| 欧美在线看片| 嫩呦国产一区二区三区av| 精品免费在线| 日韩欧美视频专区| 成人影视亚洲图片在线| 日韩毛片视频| 麻豆精品蜜桃| 亚洲欧洲美洲国产香蕉| 日韩av网站免费在线| 狠狠躁少妇一区二区三区| 日韩在线中文| 亚洲精一区二区三区| 久久精品xxxxx| 日韩毛片在线| 9色国产精品| 久久av中文| 中文在线а√天堂| 伊人网在线播放| 亚洲天堂久久| 好吊一区二区三区| 亚洲精品美女91| 国产精品亲子伦av一区二区三区| 久久免费视频66| 久久国产亚洲精品| 亚洲精品1区2区| 日韩高清中文字幕一区| 国产日韩欧美三区| 国产不卡精品在线| 亚洲香蕉网站| 中文字幕av一区二区三区四区| 日韩欧美在线精品| 国产欧美激情| 色乱码一区二区三区网站| 成人小电影网站| 久久夜夜操妹子| 免费人成网站在线观看欧美高清| 久久国内精品| 999精品在线|