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

Where's the php-src/PHP-Internals Main Entry Point

source of PHP itself 中 PHP 程序的 executing/interpreting 的主要入口点是什么函数或代码?根据我在谷歌上搜索或阅读的内容,我知道 PHP 旨在与某种服务器一起工作(甚至 CLI 命令也可以通过启动 "the command line SAPI" 来工作,它充当一个迷你-server 旨在处理单个请求),并且服务器将要求 PHP 执行程序。

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

我不知道 PHP 源代码在哪里与自己对话

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

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

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

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

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

Windows 有两个版本的 CLI,其中一个是控制台应用程序,以上述 main() 功能启动,另一个是 Windows GUI 应用程序(它在启动时不创建控制台并使用消息框进行输出)以 WinMain() 函数(文件 sapi/cli/php_cli.c, line 1198)开始。
main()WinMain() 在这里使用相同的代码。通过检查是否定义了符号 PHP_CLI_WIN32_NO_CONSOLE,它们在各处具有不同的名称和不同的代码片段。它在用于生成 Windows GUI 应用程序的文件 sapi/cli/cli_win32.c 中定义。
</Windows>

CGI版本也是一个独立的控制台应用程序。它的入口点也是文件sapi/cgi/cgi_main.c, line 1792.

中的main()函数

类似的,FPM版本在文件sapi/fpm/fpm/fpm_main.c, line 1570.

中以main()开头

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

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

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

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

  • 初始化自己;
  • 解析命令行参数(仅当它是 CLICGI 或其他类型的独立应用程序时);
  • 阅读php.ini and/or他们有的其他配置(Apache模块配置可以在.htaccess中被覆盖);
  • 使用输入文件创建流并将其传递给函数 php_execute_script() defined in file main/main.c, line 2496;
  • 清理和 return 调用进程(shell 或网络服务器)的退出代码。

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

处理它们的函数 php_execute_script() is a wrapper; it interprets the php.ini configuration entries auto_prepend_file and auto_append_file, prepares the list of files (auto-prepend file, main script, auto-append file) and passes the list to zend_execute_scripts()

php_execute_script() 并不总是被调用,某些 SAPI 和 CLI 的命令行参数会产生 zend_execute_scripts().

的直接调用

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

compiles the PHP file (and returns a list of OP codes in op_array then, if the compilation succeeds (the returned op_array is not NULL) it executes OP-codes。还有异常处理和清理;无聊的工作,但与解析和执行一样重要。

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

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

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

生成器脚本 (Zend/zend_vm_gen.php) uses zend_vm_def.h and zend_vm_execute.skl to generate zend_vm_execute.h and zend_vm_opcodes.h.

zend_vm_def.h 包含执行以处理每个 OP 代码的实际解释器代码。

PHP 核心或其捆绑扩展之一提供的某些功能的代码在哪里?

PHP 函数和扩展提供的函数的代码在某种程度上更容易理解。 PHP 核心中包含的函数位于 ext/standard directory, the functions provided by other extensions are located in files in the corresponding ext 子目录中的文件中。

在这些文件中,实现 PHP 函数的 C 函数是使用 PHP_FUNCTION() 宏声明的。比如PHP函数的实现strpos() 从文件 ext/standard/string.c, line 1948. The function strchr() being an alias of strstr() is declared using the PHP_FALIAS() macro in file ext/standard/basic_functions.c on line 2833.

开始

等等,等等。