北京赛车 pk10开奖记录_Toyou热购彩票官网
香港高速VIP雲機房火爆上線啦!無需備案慧,開通即用!配套《巔雲自助建站系統3.0》將帶給您飛一般的可視化拖拽建站體驗魯扣,歡迎免費體驗尖。

PHP原理之異常機制深入分析

一佰互聯網站制作(www.yinxi.net) 發布日期 2019-04-30 09:22:30 瀏覽數: 21

PHP的異常機制的原理是什麼?

在PHP每一個可獨立執行的op array最後的ZEND_HANDLE_EXCEPTION是用來干什麼呢?

讓我們從一個問題說起, 上周的時候, blue5tar提了一個問題:”對于下面的代碼, onError明明執行了, 但是onException卻沒有執行, 為什麼?”.

復制代碼 代碼如下:
<?php
function onError($errCode, $errMesg, $errFile, $errLine) {
echo "Error Occurred ";
throw new Exception($errMesg);
}

function onException($e) {
echo $e->getMessage();
}

set_error_handler("onError");

set_exception_handler("onException");

/* 我從不會以我的名字命名文件, 所以這個文件不存在 */
require("laruence.php");

運行結果:
復制代碼 代碼如下:
Error Occurred
PHP Fatal error: main(): Failed opening required "laruence.php

首先, 我們要知道, Require在包含一個找不到的問題的時候, 會前後拋出倆個錯誤,
復制代碼 代碼如下:
1. WARNING : 在PHP試圖打開這個文件的時候拋出.
2. E_COMPILE_ERROR : 從PHP打開文件的函數返回失敗以後拋出

而我們知道, set_error_handler是不能捕獲E_COMPILE_ERROR錯誤的:

The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called.

所以, 在onError中, 只能捕獲到第一個WARNING錯誤, 而在onError中拋出的異常, 為什麼沒有被默認exception_handler捕獲呢?

這就要說說PHP的異常機制了.

了解opcode(深入理解PHP原理之Opcodes的同學都知道, 在PHP5.3以前, 每一個可獨立運行的op array(文件, 函數, 方法)的最後一條opcode都是ZEND_HANDLE_EXCEPTION, 而這個opcode是做什麼用的呢?

原來在PHP中, 當有異常被throw的時候, 會跳到每一個op array的最後一行, 來執行這條ZEND_HANDLE_EXCEPTION, 偽碼如下:
復制代碼 代碼如下:
void on_throw_exception(zval *exception TSRMLS_DC) {
1. 判斷是否已經有異常拋出
2. 記錄exception
3. 記錄下一條要執行的op line的序號
4. 下一條要執行的op line序號 = 當前op array的最後一條
}

恩, 就和改寫ip寄存器一樣, 改寫下一條要執行的op line的序號, 就改變了程序的流向, 這樣, 就會進入到了ZEND_HANDLE_EXCEPTION的處理邏輯中.

而在ZEND_HANDLE_EXCEPTION中, 會判斷這個異常是否在try catch中,

復制代碼 代碼如下:
如果是 則把下一條要執行的op line, 置為第一個catch的op line, 並繼續執行.
如果不是 則銷毀一些不需要的變量, 和opline, 然後直接結束執行過程

有的同學要問了:”那set_exception_handler設置的異常默認處理函數(user_exception_handler)什麼時候起作用呢?”

恩, 是在執行完成退出執行LOOP以後才判斷是否有默認異常處理函數, 如果有才調用:

復制代碼 代碼如下:
//執行
zend_execute(EG(active_op_array) TSRMLS_CC);
if (EG(exception)) {
if (EG(user_exception_handler)) {
調用用戶定義的默認異常處理函數
} else {
未捕獲的異常
}
} else {
沒有異常
}
destroy_op_array(EG(active_op_array) TSRMLS_CC);
efree(EG(active_op_array));


PHP異常流程
而PHP在遇到Fatal Error的時候, 會直接zend_bailout, 而zend_bailout會導致程序流程直接跳過上面代碼段, 也可以理解為直接exit了(longjmp), 這就導致了user_exception_handler沒有機會發生作用.

了解到這些, 我想文章開頭的問題的為什麼? 也就很清晰了吧?

最後, 關于ZEND_HANDLE_EXCEPTION, 也許有同學會有疑問: 如果是這樣, 那為什麼每一個可獨立執行的op array最後都有這個ZEND_HANDLE_EXCEPTION呢? 最簡單的, 如果一個函數中不會throw, 那麼這個opcode 是明顯不需要的啊? 嘿嘿, 你很聰明, PHP 5.3開始, 已經按照你的想法調整了.. 只有在throw時刻, 才會動態的生成ZEND_HANDLE_EXCEPTION opline.

PHP5 changelog:

Changed exception handling. Now each op_array doesn"t contain ZEND_HANDLE_EXCEPTION opcode in the end. (Dmitry)
TAG標簽幕卜孔︰ PHP原理之異常機制深入分析  
一佰互聯是全國知名建站品牌服務商,我們有九年網站建設儡沖甸、網站制作軌、網頁設計匆核儈、php開發和域名注冊及虛擬主機服務經驗泌搞,提供的自助建站服務更是全國有名袓苤C近年來還整合團隊優勢自主開發了可視化多用戶”巔雲建站系統“3.0平台版玩,拖拽排版網站制作設計娠穗僳,輕松實現pc站瑯、手機微網站撩、小程序停俱、APP一體化全網營銷網站建設 碼額犁,已成功的為全國上百家網絡公司提供自助建站平台搭建服務俠摹。

相關新聞more

27
03月
php開發簡易留言板

簡介送糯︰?php/* * 模擬"留言板"*/$messageFile="message.txt";if(isset($_P... >>詳情

14
04月
專業網站制作,做網站建設最合適的時間

專業網站制作,做網站建設最合適的時間對于一個企業來說十灕谷,到底什麼時候適合做網站呢?小編覺得小公司在淡季的時候做是最合適的股,因為會把心思放在網站... >>詳情

19
03月
關于虛擬主機自助建站試用7天說明

關于虛擬主機自助建站試用7天說明在慶吉科技商務網站區<綜合網站區>選購虛擬主機皚,可以申請開通試用7天灰瀝設,這將申請門戶型網站建設朋友... >>詳情

04
04月
關于成長令,到了一定的年齡需要明白的一些事

簡介雙伍癱︰永遠要活給自己看厘簍午,而且笑容要特別燦爛朔,不要在乎別人對你的指指點點贍獻溝,只要做好你自己齡,讓看不起你的人高攀不起礬矗弧,讓看的起你的人更喜歡你生活不... >>詳情

營業執照. cdn加速服務 備案系統認證 網絡安全協會 我們的支付方式AAA認證

7x24小時服務電話:18581389571 傳真:023-85725751 免費建站交流群瘸不萊︰236412099 139947842(自助建站交流) E-Mail:post@yinxi.net 網站投訴:
重慶楚捷科技有限公司 一佰互聯©版權所有 自助建站(www.yinxi.net,Inc.) 2001-2020 All Rights Reserved 本站程序受法律保護,網站法律顧問彤懼︰ITLAW-莊毅雄律師
中華人民共和國信息產業部網站備案號:渝ICP備12000592號
pk10 pk10开奖 pk10开奖记录