手机版

深刻理解PHP原理的异常机制

时间:2021-11-23 来源:互联网 编辑:宝哥软件园 浏览:

PHP的异常机制原理是什么?PHP中每个可独立执行的op数组中最后使用的ZEND_HANDLE_EXCEPTION是什么?先问个问题。上周,blue5tar提出了一个问题:"对于下面的代码,很明显执行了一个错误,但是没有执行一个异常。为什么?”。复制代码如下:php函数onError($errCode,$errMesg,$errFile,$ errLine){ echo ' Error excepted \ n ';抛出新的Exception($ errMesg);}函数oneexception($ e){ echo $ e-getMessage();} set _ error _ handler(' OnError ');set _ exception _ handler(' OnException ');/*我从来没有用我的名字命名过文件,所以这个文件不存在*/require('lar影响力. PHP ');运行结果:并复制如下代码:出现错误PHP致命错误3360 Main () :打开必需的“影响”失败。PHP首先我们要知道,当需要的时候包含一个找不到的问题,前后会抛出两个错误。复制的代码如下: WARNING :当PHP试图打开这个文件时抛出。PHP中打开文件函数失败后抛出的E_COMPILE_ERROR :返回。我们知道,Set_error_handler是:以下错误类型无法用用户定义的函数:e _ error、e _ parse、E _ core _ error、e _ core _ warning、e _ compile _ error、e _ compile _ warning来处理,而且大部分e _ strict都是在调用set _ error _ handler()的文件中引发的。在onError中,只能捕获第一个WARNING错误,但是为什么onError中抛出的异常没有被默认的exception_handler捕获呢?有必要谈谈PHP的异常机制。了解opcode(深刻理解PHP原理的操作码)的人都知道,在PHP5.3之前,每个可独立操作的op数组(文件、函数、方法)的最后一个操作码是ZEND_HANDLE_EXCEPTION,这个操作码是用来做什么的?最初,在PHP中,当抛出异常时,它会跳到每个op数组的最后一行来执行这个ZEND_HANDLE_EXCEPTION。伪代码如下:复制代码如下: void on _ throw _ exception(zval * exception tsrmls _ DC)。{1.判断是否抛出了异常。2.记录异常。3.记录下一个要执行的操作行的序列号。4.要执行的下一个op行的序列号=当前op数组的最后一个。}嗯,就像重写ip寄存器一样,重写下一个要执行的op行的序列号会改变程序的流向。它将进入ZEND_HANDLE_EXCEPTION的处理逻辑。在ZEND_HANDLE_EXCEPTION中,会判断这个异常是否在try catch中,复制的代码如下:如果是,将下一个要执行的操作行设置为第一个捕获的操作行。并继续执行。如果没有,销毁一些不必要的变量和opline,然后直接结束执行过程。有同学要问:“set _ exception _ handler设置的异常默认处理程序什么时候生效?”?“嗯,在执行完成并退出LOOP后,判断是否有默认的异常处理功能。如果有天赋可以调用:复制代码如下: //Execute Zend _ Execute(如(active _ op _ array)tsrmls _ cc);if(eg(exception)){ if(eg(user _ exception _ handler)){调用用户定义的默认异常处理程序} else {未捕获异常} } else {无异常} destroy _ op _ array(eg(active _ op _ array)TSR mls _ cc);efree(EG(active _ op _ array));

PHP异常流注释:的图中有一个不精确的地方,就是在判断最后一个catch块是否可用的时候,会同时判断(is_a),如果是则执行最后一个catch块。但是当PHP遇到致命错误时,会直接zend _ bailout,这会导致程序流直接跳过上面的代码段。也可以理解为直接退出(longjmp),导致user_exception_handler没有机会生效。知道了这一点,我想知道为什么文章开头的问题是?很清楚吗?最后,一些学生可能对ZEND_HANDLE_EXCEPTION有疑问。如果是,为什么每个可独立执行的op数组最后都有这个ZEND_HANDLE_EXCEPTION?在最简单的情况下,如果函数中没有抛出,那么这个操作码显然是不必要的。嘿,嘿,你很聪明,PHP 5.3启动了,而且已经根据你的想法进行了调整.只有在抛出的瞬间,才会动态生成Zend _ handle _ exception op line . php5changelog : changedexception handling .现在每个op _ array最后都不包含Zend _ handle _ exception操作码。(德米特里)。

版权声明:深刻理解PHP原理的异常机制是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。