gpt4 book ai didi

php - php-src/PHP-Internals 主要入口点在哪里

转载 作者:IT王子 更新时间:2023-10-29 01:16:05 24 4
gpt4 key购买 nike

source of PHP itself 中,什么函数或代码位作为执行/解释 PHP 程序的主要入口点?根据我在谷歌搜索或在书中阅读的内容,我知道 PHP 旨在与某种服务器一起工作(甚至 CLI 命令也通过启动“命令行 SAPI”来工作,它充当设计的迷你服务器处理单个请求),并且服务器将要求 PHP 执行程序。

我知道 minitrinit生命周期函数,作为 的入口点PHP 扩展 .

我不知道的是 PHP 源代码在哪里与自身进行了这种对话

Hey look, there's a PHP program in this file/string. I ought to run it



我不是要在这里完成任何特定的任务。我试图了解 PHP 的内部结构是如何做的,并找到一个可以开始跟踪其执行的主要入口点。

最佳答案

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

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

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

适用于 Windows 的 CLI 有两个版本,其中一个是控制台应用程序,以 main() 开头。上面描述的函数,另一个是 Windows GUI 应用程序(它在启动时不创建控制台并使用消息框进行输出)以 WinMain() 开头。函数(文件 sapi/cli/php_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 版本以 main() 开头在文件中 sapi/fpm/fpm/fpm_main.c , 行 1570 .

Apache2 处理程序 是一个可动态加载的模块(在 Windows 上为 .dll,在类 Unix 系统上为 .so)。它将一些函数注册为 Web 服务器发布的事件的事件处理程序(服务器启动、加载前/后配置、处理请求等)。这些处理程序由 php_ap2_register_hook() 注册。文件中的函数 sapi/apache2handler/sapi_apache2.c , 行 738 .
(您可以在 Apache documentation 中找到有关可加载模块如何与 Apache 集成的详细信息。)

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

以类似的方式,每个 SAPI 都有一个入口点( main() 或由 Web 服务器调用的函数)。

所有这些入口点都做类似的处理:
  • 初始化自己;
  • 解析命令行参数(仅当它是 CLI CGI 或其他类型的独立应用程序时);
  • 阅读 php.ini和/或他们拥有的其他配置(Apache 模块配置可以在 .htaccess 中被覆盖);
  • 使用输入文件创建一个流并将其传递给函数 php_execute_script() 在文件 main/main.c 中定义, 行 2496 ;
  • 清理并将退出代码返回给调用进程(shell 或 Web 服务器)。

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

    函数 php_execute_script() 是一个包装器;它解释了 php.ini配置条目 auto_prepend_file auto_append_file , 准备文件列表(自动添加文件、主脚本、自动添加文件)并将列表传递给 zend_execute_scripts() 处理它们。
    php_execute_script()并不总是被调用,CLI 的一些 SAPI 和命令行参数会产生对 zend_execute_scripts() 的直接调用。 .

    zend_execute_scripts() 是有趣的事情发生的地方。

    compiles PHP 文件(并在 op_array 中返回 OP codes 的列表然后,如果编译成功(返回的 op_array 不是 NULL )它是 executes OP 代码。还有异常处理和清理; 枯燥的工作,但与解析和执行同样重要。

    编译是一个繁琐的过程。它由函数 zendparse() 完成在文件 Zend/zend_language_parser.c 中定义. zendparse()的定义函数和文件 Zend/zend_language_parser.c在 Git 存储库中无处可见;解析器是使用 bison 生成的和 re2c Zend/zend_language_parser.y 读取语言语法规则和词法标记的定义和 Zend/zend_language_scanner.l 并在文件 Zend/zend_language_parser.c 中生成实际的编译器.

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

    编译后的脚本(OP 代码列表)的执行由函数 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_vm_def.h 包含为处理每个 OP 代码而执行的实际解释器代码。

    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 .

    等等等等。

    关于php - php-src/PHP-Internals 主要入口点在哪里,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48932719/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com