详解PHP异常机制的流程及原理
2010-10-14 08:02:49 来源:WEB开发网核心提示:的异常机制了.了解opcode的同学都知道, 在PHP5.3以前, 每一个可独立运行的op array(文件, 函数, 方法)的最后一条opcode都是ZEND_HANDLE_EXCEPTION, 而这个opcode是做什么用的呢?原来在PHP中, 当有异常被throw的时候, 会跳到每一个op array的最后一行,
的异常机制了.
了解opcode的同学都知道, 在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));
更多精彩
赞助商链接