【走进php内核】之 异常处理(exception)

异常处理PHP的异常处理与其它语言的类似,在程序中可以抛出、捕获一个异常,异常抛出必须只有定义在try{...}块中才可以被捕获,捕获以后将跳到catch块中进行处理,不再执行try中抛出异常之后的代码。异常可以在任意位置抛出,然后将由最近的一个try所捕获,如果在当前执行空间没有进行捕获,那么将调用栈一直往上抛,比如在一个函数内部抛出一个异常,但是函数内没有进行try,而在函数调用的位置try了,那么就由调用处的catch捕获。接下来我们从两个方面介绍下PHP异常处理的实现。异常处理的编译
摘要由CSDN通过智能技术生成

异常处理

PHP的异常处理与其它语言的类似,在程序中可以抛出、捕获一个异常,异常抛出必须只有定义在try{...}块中才可以被捕获,捕获以后将跳到catch块中进行处理,不再执行try中抛出异常之后的代码。

异常可以在任意位置抛出,然后将由最近的一个try所捕获,如果在当前执行空间没有进行捕获,那么将调用栈一直往上抛,比如在一个函数内部抛出一个异常,但是函数内没有进行try,而在函数调用的位置try了,那么就由调用处的catch捕获。

接下来我们从两个方面介绍下PHP异常处理的实现。

异常处理的编译

异常捕获及处理的语法:

try{
    try statement;
}catch(exception_class_1 $e){
    catch statement 1;
}catch(exception_class_2 $e){
    catch statement 2;
}finally{
    finally statement;
}

try表示要捕获try statement中可能抛出的异常;catch是捕获到异常后的处理,可以定义多个,当try中抛出异常时会依次检查各个catch的异常类是否与抛出的匹配,如果匹配则有命中的那个catch块处理;finally为最后执行的代码,不管是否有异常抛出都会执行。

语法规则:

statement:
    ...
    |   T_TRY '{' inner_statement_list '}' catch_list finally_statement
            { $$ = zend_ast_create(ZEND_AST_TRY, $3, $5, $6); }
    ...
;
catch_list:
        /* empty */
            { $$ = zend_ast_create_list(0, ZEND_AST_CATCH_LIST); }
    |   catch_list T_CATCH '(' name T_VARIABLE ')' '{' inner_statement_list '}'
            { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_CATCH, $4, $5, $8)); }
;
finally_statement:
        /* empty */ { $$ = NULL; }
    |   T_FINALLY '{' inner_statement_list '}' { $$ = $3; }
;

从语法规则可以看出,try-catch-finally最终编译为一个ZEND_AST_TRY节点,包含三个子节点,分别是:try statement、catch list、finally statement,try statement、finally statement就是普通的ZEND_AST_STMT_LIST节点,catch list包含多个ZEND_AST_CATCH节点,每个节点有三个子节点:exception class、exception object及catch statement,最终生成的AST:

具体的编译过程如下:

  • (1) 向所属zend_op_array注册一个zend_try_catch_element结构,所有try都会注册一个这样的结构,与循环结构注册的zend_brk_cont_element类似,当前zend_op_array所有定义的异常保存在zend_op_array->try_catch_array数组中,这个结构用来记录try、catch以及finally开始的位置,具体结构:
typedef struct _zend_try_catch_element {
    uint32_t try_op;     //try开始的opcode位置
    uint32_t catch_op;   //第1个catch块的opcode位置
    uint32_t finally_op; //finally开始的opcode位置
    uint32_t finally_end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值