php的异常跳转的分析
来源:互联网 发布:java 对称加密 编辑:程序博客网 时间:2024/04/25 17:59
这篇博客很简单,是写给自己的,每天写一篇博客的习惯要继续。今天的博文写的主要是php中异常条转的分析。先写一段PHP的代码吧:
<?phptry { echo 'step exception one';//flag1 try { echo 'step exception two';//flag2 try { echo 'step exception three';//flag3 throw new Exception("exception"); }catch(Exception $e) { throw $e; } } catch (Exception $e) { throw $e; }} catch(Exception $e) { echo "catch the exception now";}?>
上面我们使用了3个try语句,异常一层层往上抛,PHP如何去捕获这些异常,PHP内部如何做到抛出异常。我们知道在C语言中,jmp类族函数可以实现跨函数跳转,因此我们写个简单的例子:
#include <stdio.h>#include <setjmp.h>jmp_buf buf;void step2(){ puts("now we are in step2"); longjmp(buf, 2);}void step1(){ puts("now we are in step1"); if(setjmp(buf) == 0) { puts("set jump in step1"); step2(); } else { puts("catch the jump"); }}int main(int argc, char **argv){ /** *the results: *now we are in step1 *set jump in step1 *now we are in step2 *catch the jump */ step1(); return 0;}
现在我们在加一层跳转,来模拟上述PHP的三个try catch,这个时候我们需要记录下上一步的
#include <setjmp.h>jmp_buf *buf;void step3(){ longjmp(*buf, 3);}void step2(){ puts("now we are in step2"); jmp_buf *old_buf = buf; jmp_buf now_buf; if(setjmp(now_buf) == 0) { buf = &now_buf; step3(); } else { //我们可以处理异常,也可以继续往上抛 类似于 throw longjmp(*old_buf, 2); }}void step1(){ puts("now we are in step1"); jmp_buf *old_buf; jmp_buf now_buf; if(setjmp(now_buf) == 0) { puts("set jump in step1"); buf = &now_buf; step2(); } else { puts("catch the jump"); }}//这样我可以一层层往上跳转,buf 记录上一步的jmp_buf的地址。PHP就是这样实现异常的往上逐层抛。
PHP的内部封装:
//在zend_globals.h中的struct _zend_executor_globals { //... JMP_BUF *bailout;//类似我们上边的buf,称之为中继指针 //...};//zend_portability.h定义了#ifdef HAVE_SIGSETJMP# define SETJMP(a) sigsetjmp(a, 0)# define LONGJMP(a,b) siglongjmp(a, b)# define JMP_BUF sigjmp_buf#else# define SETJMP(a) setjmp(a)# define LONGJMP(a,b) longjmp(a, b)# define JMP_BUF jmp_buf#endif//在zend.h中有定义 try之类的定义#define zend_try \ { \ JMP_BUF *__orig_bailout = EG(bailout); \ JMP_BUF __bailout; \ \ EG(bailout) = &__bailout; \ if (SETJMP(__bailout)==0) {#define zend_catch \ } else { \ EG(bailout) = __orig_bailout;#define zend_end_try() \ } \ EG(bailout) = __orig_bailout; \ }#define zend_first_try EG(bailout)=NULL; zend_try
下一篇博客我们分析一下sigsetjmp siglongjmp这2个函数吧。
0 0
- php的异常跳转的分析
- php遇到的错误与异常以及分析
- PHP跳转的一些收集
- php页面跳转的方法
- PHP实现页面的跳转
- php中页面的跳转
- php的页面跳转方式
- PHP的异常捕获
- php的异常
- php的异常处理
- PHP的异常处理
- php的异常
- 关于startActivity跳转引起的异常
- 异常的Rethrow分析
- ConcurrentModificationException 的异常分析
- ConcurrentModificationException 的异常分析
- ConcurrentModificationException 的异常分析
- 简单的PHP异常处理
- C++头文件的工作原理
- .net core使用MySQL笔记
- 关于盘口形态
- js实现瀑布流效果V2.0版本
- python3 生成可执行文件
- php的异常跳转的分析
- ORACLE in与exists语句的区别
- tomcat配置问题--j2ee学习
- Oracle启动过程突然连接失败
- container_of宏
- HTTP 状态响应码
- 在ubuntu下安装opencv配合qt工作及其中问题的解决
- '=='和equals()的区别
- CSS3--圆角