前言

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 启动流程相关推荐

  1. LIteOS学习笔记-7LiteOS启动流程与编译流程

    LIteOS学习笔记-7LiteOS启动流程与编译流程 LiteOS启动流程 1. 启动方式 2. 启动流程 硬件初始化 内核初始化 调试串口初始化 尝试进行网络连接 启动任务调度 LiteOS编译流 ...

  2. ThinkPHP5.0源码学习之框架启动流程

    ThinkPHP5框架的启动流程图如下: ThinkPHP5的启动流程按照文件分为三步: 1.请求入口(public/index.php) 2.框架启动(thinkphp/start.php) 3.应 ...

  3. Android FM模块学习之一 FM启动流程

    转自:http://blog.csdn.net/tfslovexizi/article/details/41283743 最近在学习FM模块,FM是一个值得学习的模块,可以从上层看到底层.上层就是FM ...

  4. ASP.NET Core MVC 源码学习:MVC 启动流程详解

    前言 在 上一篇 文章中,我们学习了 ASP.NET Core MVC 的路由模块,那么在本篇文章中,主要是对 ASP.NET Core MVC 启动流程的一个学习. ASP.NET Core 是新一 ...

  5. coreboot学习3:启动流程跟踪之bootblock阶段

    coreboot的第一个启动阶段为bootblock.该阶段均使用汇编语言编写.下面根据执行文件顺序介绍. 一.reset16.inc bootlbock的最开始执行的文件为src\cpu\x86\1 ...

  6. coreboot学习5:启动流程跟踪之ramstage阶段主干分析

    ramstage阶段涉及比较多的操作,比如枚举板子上的外围设备,分配资源(PCI),使能设备.本文根据该阶段的主干函数流程做分析,细节方面不涉及.理顺这个主干,从全局上把控大致流程. romstage ...

  7. coreboot学习4:启动流程跟踪之romstage阶段

    romstage是coreboot的第二个执行阶段.本文分别介绍基于qemu模拟环境的x86的跟踪,以及基于Intel baytrail平台的跟踪. 在romstage阶段,由于内存还未初始化好,所以 ...

  8. Android学习之zygote启动流程

    zygote 概述 在Android系统中,DVM(Dalvik虚拟机).应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程来创建的,我们也将它称为孵化器. zyg ...

  9. Android10.0系统启动之Launcher(桌面)启动流程-[Android取经之路]

    摘要:上一节我们讲完了Android10.0的ActivityManagerService的启动流程,在AMS的最后启动了Launcher进程,今天我们就来看看Launcher的真正启动流程. 阅读本 ...

最新文章

  1. 告别2010-正则表达式
  2. 64位 java 数据类型_全面解析Java支持的数据类型及Java的常量和变量类型
  3. 查看python版本号-Mac终端查看python版本号
  4. Spring Session——@EnableSpringHttpSession注解
  5. linux中断的上半部和下半部
  6. 计算平均指令时间_为什么向量化计算(vectorization)会这么快?
  7. 10.31模拟:总结
  8. 【源码】2012年斗地主结构算法公布(斗地主结构算法)
  9. Python跨目录引用模块(文件)
  10. 3.5 RNN 字符级语言模型
  11. vue el-tree 默认选中_Vue UI:Vue开发者必不可少的工具
  12. PDF有编辑密码怎么办?该怎么去除
  13. IM即时通讯源码系统安卓苹果IOS双端源码介绍
  14. 必须收藏!Jboss下载(全版本秒下载!)
  15. MySQL的事务特性
  16. 【托业】【新托业TOEIC新题型真题】学习笔记13-题库四-P7
  17. html外链怎么做,外链铺广之路如何走?外链实操战术整理
  18. 鸿蒙实力等级划分,从综漫开始的万界之旅
  19. 网线每根的含义以及类别和距离传输问题
  20. 端到端OCR-ABCNet论文笔记

热门文章

  1. Fiddler建好代理后,能连到手机,但手机不能上网了,求破有果
  2. PHP 数组遍历 foreach 语法结构
  3. Linux文本处理命令:cut grep awk sed printf
  4. Mysql数值型字符串按照数值进行排序
  5. 打开闪光灯_用手机拍照这么久,你居然还不知道闪光灯怎么用
  6. python画统计图怎么在右上角表示哪条线代表什么_Python-matplotlib统计图之箱线图漫谈...
  7. html坐标定位图解,HTML5地理定位实例
  8. zend framework1.12 没找到php.exe,请加一个zend framework的有关问题
  9. php js获取文件大小,js+ajax实现获取文件大小的方法_javascript技巧
  10. linux zip和tar的区别,Linux入门:tar、gzip、bzip2以及zip的区别