首頁  >  文章  >  php教程  >  php核心分析(八)-zend_compile

php核心分析(八)-zend_compile

黄舟
黄舟原創
2016-12-19 11:30:571730瀏覽

摘要:這裡閱讀的php版本為PHP-7.1.0 RC3,閱讀程式碼的平台為linux回到之前看的zend_eval_stringlZEND_API int zend_eval_stringl(char *str, size_t str_len, zval *retval_ptr, char *string_name) { */ { ... new_o ...

這裡閱讀的php版本為PHP-7.1.0 RC3,閱讀程式碼的平台為linux

回到之前看的zend_eval_stringl

01    ZEND_API int zend_eval_stringl(char *str, size_t str_len, zval *retval_ptr, char *string_name) /* {{{ */    
02    {    
03        ...    
04        new_op_array = zend_compile_string(&pv, string_name);  // 这个是把php代码编译成为opcode的过程    
05        ...    
06        zend_execute(new_op_array, &local_retval); // 这个是具体的执行过程,执行opcode,把结果存储到local_retval中    
07        ...    
08        retval = SUCCESS;    
09        return retval;    
10    }

這裡的zend_execute執行了兩步,第一步就是把php編譯解析變成opcode的過程,我們就先來看這個。

zend_compile_string

zend_compile_string函數追下去可以追到compile_string

01    // 将一个字符串解析成为op_array    
02    zend_op_array *compile_string(zval *source_string, char *filename)    
03    {    
04         zend_lex_state original_lex_state;    
05         zend_op_array *op_array = NULL;    
06         zval tmp;    
07    
08        // 如果传进来要解析的字符为空,则返回null    
09         if (Z_STRLEN_P(source_string)==0) {    
10              return NULL;    
11         }    
12    
13         ZVAL_DUP(&tmp, source_string); // 复制source_string到zval中    
14         convert_to_string(&tmp); // 如果不是字符类型就转换为字符类型    
15         source_string = &tmp;    
16    
17         zend_save_lexical_state(&original_lex_state); // 保存lex上下文    
18         if (zend_prepare_string_for_scanning(source_string, filename) == SUCCESS) {  // 做编译前的准备    
19              BEGIN(ST_IN_SCRIPTING); // 设置状态为正在编译    
20              op_array = zend_compile(ZEND_EVAL_CODE); // 进行编译,并把生成结果放在op_array中    
21         }    
22    
23         zend_restore_lexical_state(&original_lex_state); // 恢复lex上下文    
24         zval_dtor(&tmp); // 释放tmp    
25    
26         return op_array;    
27    }

裡面最核心的就是zend_compile了。這裡的幾個點可以看看:

1 這麼做型轉換,參考convert_to_string。這個函數就是把任意型別的值轉換成zval的string類型。
2 zval_dtor,這個函數是能把任意的zval變數做回收。非常好用。
3 ZVAL_DUP,是進行複製,它和ZVAL_COPY的差別在於是否增加gc的引用計數。

 以上就是php核心分析(八)-zend_compile的內容,更多相關內容請關注PHP中文網(www.php.cn)! 


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn