代码之家  ›  专栏  ›  技术社区  ›  Alana Storm

php src/php内部构件的主要入口点在哪里

  •  29
  • Alana Storm  · 技术社区  · 8 年前

    在中执行/解释PHP程序的主要入口点是什么函数或代码位 source of PHP itself ? 根据我在google上搜索或在书中读到的内容,我知道PHP设计用于某种服务器(甚至CLI命令都是通过启动“命令行SAPI”来工作的,该命令充当一个设计用于处理单个请求的小型服务器),并且服务器会要求PHP执行一个程序。

    我知道 minit rinit 生命周期功能,作为 PHP扩展 .

    我不知道的是,PHP源代码在哪里进行了这样的对话

    嘿,看,这个文件/字符串中有一个PHP程序。我应该运行它

    我不想在这里完成任何具体任务。我试图理解PHP的内部结构是如何工作的,并找到一个主要的入口点,在这里我可以开始跟踪它的执行。

    1 回复  |  直到 8 年前
        1
  •  52
  •   axiac    8 年前

    某些SAPI的代码入口点在哪里?

    这个 CLI 是一个独立的应用程序。与用C编写的任何其他应用程序一样,它的入口点是函数 main() (文件 sapi/cli/php_cli.c 线 1200 ):

    int main(int argc, char *argv[])
    

    用于Windows的CLI有两个版本,其中一个是控制台应用程序,从 main() 另一个是Windows GUI应用程序(启动时不创建控制台,并使用消息框进行输出),它以 WinMain() 函数(文件 sapi/cli/php\u cli。c 线 1198 ).
    main() WinMain() 在此处使用相同的代码。通过检查符号是否 PHP_CLI_WIN32_NO_CONSOLE 已定义。它在文件中定义 sapi/cli/cli_win32.c 用于生成Windows GUI应用程序的。
    </Windows>

    这个 CGI 版本也是一个独立的控制台应用程序。其入口点也是 main() 文件中的函数 sapi/cgi/cgi_main.c 线 1792 .

    与此类似 FPM公司 版本以开头 在文件中 sapi/fpm/fpm/fpm_main.c 线 1570 .

    Apache2处理程序 是一个可动态加载的模块( .dll 在Windows上, .so 在类Unix系统上)。它将一些函数注册为web服务器发布的事件的事件处理程序(服务器启动、加载前/后配置、进程请求等)。这些处理程序由 php_ap2_register_hook() 文件中的函数 sapi/apache2handler/sapi_apache2.c 线 738 .
    (您可以在 Apache documentation .)

    我们感兴趣的处理程序是函数 php_handler() 调用以处理HTTP请求的。

    main() 或由web服务器调用的函数)。

    所有这些入口点都进行类似的处理:

    • 初始化自身;
    • 分析命令行参数(仅当 CLI , CGI 或其他类型的独立应用程序);
    • 阅读 php.ini 和/或他们拥有的其他配置(Apache模块配置可以在 .htaccess );
    • 使用输入文件创建流并将其传递给函数 php_execute_script() 在文件中定义 main/main.c 线 2496 ;
    • 清理并向调用进程(shell或web服务器)返回退出代码。

    实际执行PHP脚本的代码在哪里?

    功能 php\u execute\u脚本() 是一个包装器;它解释了 php。ini公司 配置条目 auto_prepend_file auto_append_file ,准备文件列表(自动前置文件、主脚本、自动追加文件)并将列表传递给 zend_execute_scripts() 处理它们。

    php\u execute\u脚本() 并不总是调用,CLI的一些SAPI和命令行参数会直接调用 zend\u execute\u脚本() .

    zend\u execute\u脚本() 是有趣的事情发生的地方。

    compiles PHP文件(并返回 OP codes 在里面 op_array 然后,如果编译成功(返回 op\U阵列 不是 NULL )it部门 executes OP代码。还有异常处理和清理;枯燥的工作,但与解析和执行一样重要。

    编译是一个乏味的过程。它由函数完成 zendparse() 在文件中定义 Zend/zend_language_parser.c . 定义 zendparse() 函数和文件 Zend/Zend\u语言分析器。c 在Git回购中看不到;解析器是使用 bison re2c 从中读取语言语法规则和词汇标记的定义 Zend/zend_language_parser.y Zend/zend_language_scanner.l 并在文件中生成实际编译器 Zend/Zend\u语言分析器。c .

    然而,即使在repo中看不到艰苦的工作,编译过程中有趣的部分也可以在上面提到的文件中看到。

    编译脚本(操作代码列表)的执行由函数完成 zend_execute() 文件中定义的 Zend/zend_vm_execute.h . 这也是一个生成的文件,有趣的是它是由PHP脚本生成的。

    Zend/zend_vm_gen.php )使用 zend_vm_def.h zend_vm_execute.skl 生成 zend_vm_execute.h zend_vm_opcodes.h .

    zend\u vm\u def。h类 包含为处理每个操作代码而执行的实际解释器代码。

    PHP核心或其捆绑扩展提供的某些函数的代码在哪里?

    PHP函数和扩展提供的函数的代码更容易理解。PHP核心中包含的函数位于 ext/standard 目录中,其他扩展提供的函数位于相应 ext

    在这些文件中,实现PHP函数的C函数是使用 PHP_FUNCTION() 宏。例如,PHP函数的实现 strpos() 在文件中启动 ext/standard/string.c 线 1948 . 功能 strchr() 作为的别名 strstr() 使用 PHP_FALIAS() ext/standard/basic_functions.c 在线 2833 .

    等等,等等。

    推荐文章