php7.0 cli,PHP-7.1 源代码学习:php-cli 启动流程
前言
php cli main 函数
configure & make 默认构建目标为 php-cli,相关代码在 sapi/cli 目录下,php_cli.c 文件中能够找到 main(入口)函数,大概流程如下:
命令行参数处理
cli_sapi_module 初始化
sapi_module->startup
do_cli or do_cli_server
清理工作
sapi_module_struct
C 语言系统编程常用手法,通过 struct 中声明 函数指针 类型的字段来实现类似面向对象中抽象类的概念,在 main/SAPI.h 文件中可以找到该结构体的定义,这里只列出部分字段(下同):
struct _sapi_module_struct {
char *name;
char *pretty_name;
int (*startup)(struct _sapi_module_struct *sapi_module);
int (*shutdown)(struct _sapi_module_struct *sapi_module);
...
char *ini_entries;
const zend_function_entry *additional_functions;
unsigned int (*input_filter_init)(void);
}
cli_sapi_module
cli_sapi_module 是一个静态全局变量,定义在 php_cli.c 中,你可以将它理解成是 sapi_module_struct "类" 的一个 "实例",结构体中 "挂载" 了 cli 特定的实现函数:
/* {{{ sapi_module_struct cli_sapi_module
*/
static sapi_module_struct cli_sapi_module = {
"cli", /* name */
"Command Line Interface", /* pretty name */
...
php_cli_startup, /* startup */
php_module_shutdown_wrapper, /* shutdown */
...
STANDARD_SAPI_MODULE_PROPERTIES
};
do_cli
do_cli 函数定义在 php_cli.c 文件中,大致流程如下:
根据命令行选项 确定 behavior(解释器行为)
根据 behavior 执行相应的动作
通过执行 sapi/cli/php --help 可以查看所有的 php-cli 命令行选项,我们通过几个简单的选项来分析解释器执行流程
PHP_MODE_CLI_DIRECT
该模式下,php-cli 会执行解释执行通过命令行参数传递的 code
case PHP_MODE_CLI_DIRECT:
cli_register_file_handles();
if (zend_eval_string_ex(exec_direct, NULL,
"Command line code", 1) == FAILURE) {
exit_status=254;
}
break;
追踪 zend_eval_string_ex 的函数调用,定位到 zend_execute_API.c 文件中 zend_eval_stringl 函数,代码逻辑已经很清楚了:先调用 zend_compile_string 函数编译代码生成字节码 new_op_array,再调用 zend_execute 函数执行生成的字节码
ZEND_API int zend_eval_stringl(char *str, size_t str_len, zval *retval_ptr,
char *string_name) {
...
original_compiler_options = CG(compiler_options);
CG(compiler_options) = ZEND_COMPILE_DEFAULT_FOR_EVAL;
new_op_array = zend_compile_string(&pv, string_name);
CG(compiler_options) = original_compiler_options;
if (new_op_array) {
zend_try {
ZVAL_UNDEF(&local_retval);
zend_execute(new_op_array, &local_retval);
} zend_catch {
destroy_op_array(new_op_array);
efree_size(new_op_array, sizeof(zend_op_array));
zend_bailout();
} zend_end_try();
...
} else {
retval = FAILURE;
}
zval_dtor(&pv);
return retval;
}
zend_compile_string 属于语法分析内容,参考 PHP-7.1 源代码学习: 语法分析,这里做个简要介绍
compile_string
通过搜索源代码可以发现 zend_compile_string 最终调用 compile_string
zend_op_array *compile_string(zval *source_string, char *filename)
{
zend_lex_state original_lex_state;
zend_op_array *op_array = NULL;
zval tmp;
if (Z_STRLEN_P(source_string)==0) {
return NULL;
}
ZVAL_DUP(&tmp, source_string);
convert_to_string(&tmp);
source_string = &tmp;
zend_save_lexical_state(&original_lex_state);
if (zend_prepare_string_for_scanning(source_string, filename) == SUCCESS) {
BEGIN(ST_IN_SCRIPTING);
op_array = zend_compile(ZEND_EVAL_CODE);
}
zend_restore_lexical_state(&original_lex_state);
zval_dtor(&tmp);
return op_array;
}
总结
php7.0 cli,PHP-7.1 源代码学习:php-cli 启动流程相关推荐
- LIteOS学习笔记-7LiteOS启动流程与编译流程
LIteOS学习笔记-7LiteOS启动流程与编译流程 LiteOS启动流程 1. 启动方式 2. 启动流程 硬件初始化 内核初始化 调试串口初始化 尝试进行网络连接 启动任务调度 LiteOS编译流 ...
- ThinkPHP5.0源码学习之框架启动流程
ThinkPHP5框架的启动流程图如下: ThinkPHP5的启动流程按照文件分为三步: 1.请求入口(public/index.php) 2.框架启动(thinkphp/start.php) 3.应 ...
- Android FM模块学习之一 FM启动流程
转自:http://blog.csdn.net/tfslovexizi/article/details/41283743 最近在学习FM模块,FM是一个值得学习的模块,可以从上层看到底层.上层就是FM ...
- ASP.NET Core MVC 源码学习:MVC 启动流程详解
前言 在 上一篇 文章中,我们学习了 ASP.NET Core MVC 的路由模块,那么在本篇文章中,主要是对 ASP.NET Core MVC 启动流程的一个学习. ASP.NET Core 是新一 ...
- coreboot学习3:启动流程跟踪之bootblock阶段
coreboot的第一个启动阶段为bootblock.该阶段均使用汇编语言编写.下面根据执行文件顺序介绍. 一.reset16.inc bootlbock的最开始执行的文件为src\cpu\x86\1 ...
- coreboot学习5:启动流程跟踪之ramstage阶段主干分析
ramstage阶段涉及比较多的操作,比如枚举板子上的外围设备,分配资源(PCI),使能设备.本文根据该阶段的主干函数流程做分析,细节方面不涉及.理顺这个主干,从全局上把控大致流程. romstage ...
- coreboot学习4:启动流程跟踪之romstage阶段
romstage是coreboot的第二个执行阶段.本文分别介绍基于qemu模拟环境的x86的跟踪,以及基于Intel baytrail平台的跟踪. 在romstage阶段,由于内存还未初始化好,所以 ...
- Android学习之zygote启动流程
zygote 概述 在Android系统中,DVM(Dalvik虚拟机).应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程来创建的,我们也将它称为孵化器. zyg ...
- Android10.0系统启动之Launcher(桌面)启动流程-[Android取经之路]
摘要:上一节我们讲完了Android10.0的ActivityManagerService的启动流程,在AMS的最后启动了Launcher进程,今天我们就来看看Launcher的真正启动流程. 阅读本 ...
最新文章
- 告别2010-正则表达式
- 64位 java 数据类型_全面解析Java支持的数据类型及Java的常量和变量类型
- 查看python版本号-Mac终端查看python版本号
- Spring Session——@EnableSpringHttpSession注解
- linux中断的上半部和下半部
- 计算平均指令时间_为什么向量化计算(vectorization)会这么快?
- 10.31模拟:总结
- 【源码】2012年斗地主结构算法公布(斗地主结构算法)
- Python跨目录引用模块(文件)
- 3.5 RNN 字符级语言模型
- vue el-tree 默认选中_Vue UI:Vue开发者必不可少的工具
- PDF有编辑密码怎么办?该怎么去除
- IM即时通讯源码系统安卓苹果IOS双端源码介绍
- 必须收藏!Jboss下载(全版本秒下载!)
- MySQL的事务特性
- 【托业】【新托业TOEIC新题型真题】学习笔记13-题库四-P7
- html外链怎么做,外链铺广之路如何走?外链实操战术整理
- 鸿蒙实力等级划分,从综漫开始的万界之旅
- 网线每根的含义以及类别和距离传输问题
- 端到端OCR-ABCNet论文笔记
热门文章
- Fiddler建好代理后,能连到手机,但手机不能上网了,求破有果
- PHP 数组遍历 foreach 语法结构
- Linux文本处理命令:cut grep awk sed printf
- Mysql数值型字符串按照数值进行排序
- 打开闪光灯_用手机拍照这么久,你居然还不知道闪光灯怎么用
- python画统计图怎么在右上角表示哪条线代表什么_Python-matplotlib统计图之箱线图漫谈...
- html坐标定位图解,HTML5地理定位实例
- zend framework1.12 没找到php.exe,请加一个zend framework的有关问题
- php js获取文件大小,js+ajax实现获取文件大小的方法_javascript技巧
- linux zip和tar的区别,Linux入门:tar、gzip、bzip2以及zip的区别