要約: ここで読み取った php のバージョンは PHP-7.1.0 RC3 で、コードを読み込むためのプラットフォームは Linux です。 int zend_eval_stringl(char *str, size_t str_len, zval *retval_ptr, char) の前に読んだ zend_eval_stringlZEND_API に戻ります。 *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は2つのステップを実行します。最初のステップは、phpをコンパイルしてオペコードに解析するプロセスです。最初にこれを見ていきます。
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 の文字列型に変換します。
2 zval_dtor、この関数は任意の zval 変数をリサイクルできます。完璧に機能しました。
3 ZVAL_DUPはコピー用です。 ZVAL_COPYとの違いはgcの参照数を増やすかどうかです。
上記は PHP カーネル解析 (8) - zend_compile の内容です。さらに関連する内容については、PHP 中国語 Web サイト (www.php.cn) に注目してください。