摘要:这里阅读的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
立即学习“PHP免费学习笔记(深入)”;
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)!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号