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

时间:2018-02-22 16:39:21

标签: php php-internals

source of PHP itself中,哪些函数或代码作为执行/解释PHP程序的主要入口点?基于我用Google搜索或阅读的书籍,我知道PHP旨在与某种服务器一起工作(即使CLI命令通过启动"命令行SAPI"来工作,充当用于处理单个请求的迷你服务器,并且服务器将要求PHP执行程序。

我了解minitrinit生命周期函数,它们是 PHP扩展的入口点。

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

  

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

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

1 个答案:

答案 0 :(得分:50)

某些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_cli.c,行1198)开头。
main()WinMain()在此处使用相同的代码。通过检查符号PHP_CLI_WIN32_NO_CONSOLE是否已定义,它们具有不同的名称和不同的代码片段。它在文件sapi/cli/cli_win32.c中定义,用于生成Windows GUI应用程序 </Windows>

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

类似地, FPM 版本以文件sapi/fpm/fpm/fpm_main.c中的main()1570开头。

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

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

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

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

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

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

函数php_execute_script()是一个包装器;它解释php.ini配置条目auto_prepend_fileauto_append_file,准备文件列表(自动前置文件,主脚本,自动附加文件)并将列表传递给{{3}处理它们。

不总是调用

php_execute_script(),CLI的某些SAPI和命令行参数会生成zend_execute_scripts()的直接调用。

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

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

汇编是一个繁琐的过程。它由文件zendparse()中定义的函数Zend/zend_language_parser.c完成。在Git回购中无处可见zendparse()函数和文件Zend/zend_language_parser.c的定义;解析器是使用bisonre2c生成的,它从executesZend/zend_language_parser.y读取语言语法规则和词法标记的定义,并在文件{{1}中生成实际的编译器}}

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

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

生成器脚本(Zend/zend_vm_execute.h)使用Zend/zend_vm_gen.phpzend_vm_def.h生成zend_vm_execute.sklzend_vm_execute.h

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

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

扩展提供的PHP函数和函数的代码在某种程度上更容易理解。 PHP核心中包含的函数位于zend_vm_def.h目录中的文件中,其他扩展提供的函数位于相应ext/standard子目录中的文件中。

在这些文件中,使用zend_execute()宏声明了实现PHP函数的C函数。例如,PHP函数ext的实现 从文件strpos()开始,行ext/standard/string.c。函数1948strchr()的别名是使用strstr()ext/standard/basic_functions.c文件中的PHP_FUNCTION()宏声明的。

等等,等等。