php sapi生命周期

php api 扩展 执行 编程技术
发布日期 2023-06-02 更新日期 2023-06-03 阅读次数 87 文章字数 3.1k

sapi全程为Server Abstraction API,即抽象服务应用编程接口。

应用服务,常见的有php-cli以及php-fpm,前者为命令行服务,后者是web服务

从sapi层面来看,生命周期经历5个阶段

main()->php_module_startup()->php_request_startup()->php_excute_script()->php_request_shutdown()->php_module_shutdown()

在fpm模式下因为是常驻服务,request_startup()->excute_script()->request_shutdown()通常会多次执行

可以在php扩展【php-module】里测试生命周期,分别对应PHP_MINIT【M就是module缩写,init表示start】,PHP_RINIT【request_start】,PHP_RSHUTDOWN【request_shutdown】,PHP_MSHUTDOWN【module_shutdown】

php module_start()

php模块初始化阶段

  1. sapi_active():主要是初始化sapi全局变量,尤其是sapi_headers和request_info
  2. php_output_startup():主要是初始化output全局变量以及output handler相关的冲突表
  3. php_start_ticks():初始化定时器
  4. gc_globals_ctor():初始化gc垃圾回收器,即初始化gc全局变量
  5. zend_startup():
    1.  启动zend引擎:启动zend内存管理器;设置编译器句柄、执行器句柄以及opcodes句柄;
    2. 初始化全局函数表、全局类表、全局常量表、以及超全局常量表;
    3. 注册底层内置的扩展即Code扩展(zend_builtin_module)以及隶属该扩展的functions;
    4. 注册zend相关的标准常量,初始化php.ini配置符号等
  6. REGIST_XXX_CONSTANT():注册php相关的标准常量
  7. php_init_config()
    1. 解析php.ini配置并报存到configuration_hash表中
    2. 初始化extension_lists.engine和extension_lists.functions
  8. REGIST_INI_ENTRIES():将configuration_hash表中的Core配置辐射到对应的Core全局变量
  9. zend_register_standard_ini_entries():将configuration_hash表中的standard配置辐射到对应的standard扩展当中,即注入到该扩展对应的全局空间
  10. php_startup_auto_globals():注册超全局变量
  11. php_register_internal_extensions():注册底层内置的扩展以及隶属该扩展的函数
  12. php_ini_register_extensions():注册用户自定义的扩展以及隶属该扩展的函数
  13. zend_start_modules():执行各个php扩展的HOOK:module->module_startup_func()
  14. zend_startup_extensions():执行各个zend扩展的HOOK:extension->startup()
  15. zend_collect_module_handlers():主要是收集各个扩展的request
  16. php_disable_functions/classes():主要是禁用php.ini所设定的函数和类
  17. sapi_deactivate():对应于sapi_active(),主要是重置SG的sapi_headers,request_info

php_request_start()

php请求阶段初始化

  1. php_output_activate():激活php输出
  2. zend_activate():激活zend引擎,主要包括:
    1. 重置垃圾回收器;初始化编译器;初始化执行器;初始化词法和语法分析器
    2. 初始化全局变量符号表;初始化included文件符号表
    3. 执行zend引擎扩展的HOOK:extension->activate()
  3. sapi_activate():...
  4. php_hash_environment():主要是“惰性”初始化超全局变量
  5. zend_activate_modules():执行各个php扩展的HOOK:module->request_startup_func()

php_excute_script()

php脚本执行阶段【严格来说是解析+编译+执行】

php代码-->RE2C->Token->YACC
->AST抽象语法树->Zend编译器
->Opcodes->Zend执行器->Output

php_request_shutdown()

PHP请求关闭阶段

  1. php_call_shutdown_functions():依次执行register_shutdown_function()注册的HOOK函数
  2. zend_call_destructors():执行所有的_destruct函数,伴有清理全局变量符号表
  3. php_output_discard_all()/php_output_end_all():刷新所有的php输出缓冲
  4. zend_unset_timeout():重置php的最大执行时间max_execution_time
  5. zend_deactive_modules():执行各个php扩展的HOOK:module->request_shutdown_func()
  6. php_output_deactivate():关闭php输出,发送HTTP响应头,清理输出句柄
  7. php_free_shutdown_functions():依次释放通过register_shutdown_function()注册的HOOK函数
  8. zval_ptr_dtoc(&PG(http_globals)[i]):释放超全局变量PG(http_globals)
  9. php_free_request_globals():释放last_error以及sys_temp_dir成员所占的内存
  10. zend_deactivate():
    1. 关闭词法和语法分析器;关闭编译器;关闭执行器;恢复ini_entries
    2. 执行各个zend扩展的HOOK:extension->deactivate()
  11. zend_post_deactive_modules():执行所有扩展的HOOK:xxx->post_shutdown_func()
  12. sapi_deactivate():对应于sapi_activate(),主要是重置SG的sapi_headers和request_info
  13. virtual_cwd_deactive():释放虚拟工作目录所占用的内存
  14. php_shutdown_stream_hashes():关闭流包装类和流过滤器
  15. shutdown_memory_manager():关闭内存管理器
  16. zend_unset_timeout():重置php的最大执行时间max_execution_time

php_module_shutdown()

模块关闭阶段

  1. sapi_flush():分别调用执行各个sapi模块对应的flush()句柄
  2. zend_destroy_rsrc_list(&EG(persistent_list)):清理持久化的符号表
  3. zend_destroy_modules():执行各个php扩展的HOOK:module->module_shutdown_func()
  4. zend_shutdown_extensions():执行各个zend扩展的HOOK:extension->shutdown(_func()
  5. shutdown_memory_manager():关闭内存管理器
  6. php_output_shutdown():关闭php输出
  7. core_globals_dtoc():释放php核心全局变量

 


文章作者: 朱丰华

文章链接: https://smart.52dixiaowo.com/blog/post-415.html

版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。

php api 扩展 执行

发表评论

相关推荐
朱丰华   |   7个月前   |   php

php判断是否被iframe

221    评论    点赞
朱丰华   |   1年前   |   linux · upx

Linux下安装UPX

406    评论    点赞
朱丰华   |   1年前   |   php

php正则表达式定界符:异常Delimiter must not be alphanumeric or backslash

190    评论    点赞
朱丰华   |   1年前   |   请求 · 一个

ab测压命令,apache测压工具

172    评论    点赞
朱丰华   |   1年前   |   php · 缓存 · opcache

php 加速、提高并发opcache

198    评论    点赞
朱丰华   |   1年前   |   js · 重复

js如何避免重复监听addEventListener事件?

124    评论    点赞
朱丰华   |   1年前   |   编译 · linux · 平台

Go 交叉编译 (跨平台编译)

173    评论    点赞
朱丰华   |   1年前   |   正则 · 表达

正则表达式,实现if...then...else

113    评论    点赞
朱丰华   |   1年前   |   mysql · 变量 · sql

MySQL实现行号-自定义变量

113    评论    点赞
朱丰华   |   1年前   |   sql · php

PHP如何使用PDO批量执行SQL?

115    评论    点赞
朱丰华   |   1年前   |   sed · 文件

Shell 指定行处理head、tail、sed

156    评论    点赞
朱丰华   |   1年前   |   php · 字符 · 字符串

如何在 PHP 中将字符串的第一个字母转换为大写

150    评论    点赞
朱丰华   |   1年前   |   php · 字符 · 正则

php正则表达式原生字符

86    评论    点赞
朱丰华   |   1年前   |   字符 · php · 比较

PHP比较字符串大小相关函数

111    评论    点赞
朱丰华   |   1年前   |   文件 · linux · 修改

linux文件的三个时间atime,mtime,ctime分别表示什么?

275    评论    点赞
朱丰华   |   1年前   |   php

windows下编写、编译php扩展

158    评论    点赞
朱丰华   |   1年前   |   linux · php

linux下编写、编译php扩展

150    评论    点赞
朱丰华   |   1年前   |   html

npm clean-mark,抓取网页文章内容,转换成markdown、html、txt

192    评论    点赞
朱丰华   |   1年前   |   js · vue · 监听

js vue监听,深度监听

114    评论    点赞
朱丰华   |   1年前   |   php · 混淆 · obfuscate · git

yakpro-po混淆php代码

106    评论    点赞
{{item.author_name}}   |   {{new Date(item.date*1000).log()}}   |   {{it}} ·

{{item.title}}

{{item.uv}}    评论    点赞