文章来自:https://blog.csdn.net/weixin_33904756/article/details/88857180作者:phper点击加入:PHP自学中心技术交流微信群商务合作: 请加微信(QQ):
2230304070技术交流微信群我们在学习中单枪匹马,还不如一次短短的交流,你可以在别人吸取各种学习经验学习方法以及学习技巧,所以,学习与交流少不了一个圈子,提升你的学习技能请点击加技术群:PHP自学中心交流群。
视频教程分享1 Linux从零入门实战-2019年七月Z线公众号里回复:082500232 Git版本管理视频教程公众号里回复:201901023 web前端视频教程(基础+中级+高级)公众号里回复:20181226
4 Laravel5.x底层实战兼核心源码解析链接:http://www.mano100.cn/thread-344-1-1.html5由浅入深析ThinkPHP5和ThinkPHP6底层源码链接:http:
//www.mano100.cn/thread-1-1-1.html6全方位深度剖析PHP7底层源码(完整版)链接:http://www.mano100.cn/thread-93-1-1.html精选文章正文
php是一门适用于web开发的动态语言,它可以说是一个用C语言实现的包含大量组件的软件框架那么,php是如何工作的呢?它的生命周期是怎么样的呢?表层分析php是以请求/响应为周期运行服务端应用程序,当请求进入应用程序,流程如下:。
php的每一个请求都会重复以上的交互底层分析php的运行模式有两种:web模式和cli模式无论是哪种公众模式,php的工作原理都是一样的,都是作为一种SAPI运行首先,认识下SAPI是什么?Sapi全称是Server Application Programming Interface,也就是服务端应用编程接口。
Sapi通过一系列钩子函数,使得PHP可以和外围交互数据,这是PHP非常优雅和成功的一个设计,通过sapi成功的将PHP本身和上层应用解耦隔离PHP可以不再考虑如何针对不同应用进行兼容,而应用本身也可以针对自己的特点实现不同的处理方式。
常见的SAPI有cli、cgi、php-fpm以及各服务具体的sapi。生命周期在php的生命周期中,有4个关键调用:
以nginx服务器为例,在web模式下,生命周期流程如下:
SAPI运行PHP都经过下面几个阶段:1、模块初始化阶段(module init)这个阶段主要进行PHP框架和Zend引擎的初始化操作该阶段的入口函数为php_module_startup()这个阶段一般只在SAPI启动时执行一次,对于Fpm而言,就是在Fpm的。
master进程启动时执行的该阶段的几个主要处理如下:激活SAPI:sapi_activate(),初始化请求信息SG(request_info)、设置读取POST请求的handle等启动PHP输出:php_output_startup()
初始化垃圾回收器:gc_globals_ctor(),并分配zend_gc_globals内存启动Zend引擎:zend_startup(),主要操作包括1 启动内存池 start_memory_manager()。
2 设置一些util函数句柄,如zend_error_cb、zend_pringf````、zend_write```等3 设置Zend虚拟机编译、执行器的函数句柄zend_compile_file、zend_execute_ex
、垃圾回收函数句柄gc_collect_cycles4 分配函数符号表 方法符号表(function_table)、类符号表(class_table)、常量符号表(zend_constants)等,如果是多线程的话,还会分配编译器、执行器的全局变量
5 注册Zend核心扩展:zend_startup_builtin_funtions(),这个扩展是内核提供的,该过程将注册Zend核心扩展提供的函数,如strlen、define、func_get_args
、class_exists等6 注册Zend定义的标准常量:zend_register_standard_constants(),比如E_ERROR、E_WARNING、E_ALL、TRUE、FALSE。
等7 注册$GLOBALS超全局变量的获取handle8 分配php.ini配置的存储符号表 EG(ini_directives)注册PHP定义的常量:PHP_VERSION、PHP_ZTS、PHP_SAPI。
等解析php.ini:解析完成后所有的php.ini配置保存在configuration_hash哈希表中映射PHP、Zend核心的php.ini配置:根据解析出的php.ini,获取对应的配置值,将最终的配置插入EG(ini_directives)哈希表。
注册用于获取$_GET、$_POST、$_COOKIE、$_SERVER、$_ENV、$_REQUEST、$_FILES变量的handle注册静态编译的扩展:php_register_internal_extensions_func()。
注册动态加载的扩展:php_init_register_extensions(),将php.ini中配置的扩展加载到PHP中回调各扩展定义的module startup钩子函数,即通过PHP_MINIT_FUNCTION()。
定义的函数注册php.ini中禁用的函数、类:disable_funstions、disable_classes2、请求初始化阶段(request init)当一个页面请求发生时,在请求处理前都会经历的一个阶段。
对于fpm而言,是在worker进程accept一个请求并读取、解析完请求数据后的一个阶段在这个阶段内,SAPI层将控制权交给PHP层,PHP初始化本次请求执行脚本所需的环境变量该阶段的处理函数为php_request_startup()。
主要处理有以下几个:(1)激活输出:php_output_activate()(2)激活Zend引擎:zend_activate(),主要操作有(2.1)重置垃圾回收器:gc_reset()(2.2)初始化编译器:。
ini_compiler()(2.3)初始化执行器:ini_exexutor(),将 EG(function_table)和 EG(class_table)分别执行 CG(function_table)和CG(
class_table)(2.4)初始化全局变量符号表 EG(symbol_table)、include过的文件符号表 EG(included_files)(2.5)初始化词法扫描器:sapi_activate()。
(3)激活SAPI:sapi_activate()(4)回调个扩展定义的request startup钩子函数:zend_activate_modules()3、php脚本执行阶段(execute sccript)
(1)该阶段包括PHP代码的编译、执行两个核心阶段,这也是Zend引擎最重要的功能(2)在编译阶段,PHP脚本将经历从PHP源代码到抽象语法树,再到opline指令的转化过程,最终生成的opline指令就是Zend引擎可识别的执行指令,这些指令被执行器执行,这就是PHP代码解释执行的过程。
该阶段入口函数为php_execute_script()4、请求结束阶段(request shutdown)(1)该阶段将flush输出内容、发送HTTP应答header头、清理局部变量、关闭编译器、关闭执行器等。
(2)另外,在该阶段将回调各扩展的request shutdown钩子函数(3)该阶段与请求初始化阶段操作是相反的5、模块关闭阶段(module shutdown)该阶段在SAPI关闭时执行,与模块初始化阶段对应,这个阶段主要是进行资源的清理、php各模块的关闭操作,同时,将回调各扩展的。
module shutdown钩子函数这是发生在所有请求都已经结束之后,例如关闭fpm的操作(这个是对于CGI和CLI等SAPI,没有“下一个请求”,所以SAPI立刻开始关闭)注:根据不同SAPI的实现,各阶段的执行情况会有一些差异,比如命令行模式下,每次执行一个脚本都会完成的经历这些阶段。
而FastCgi模式下则在启动时执行一次模块初始化,然后各个请求只经历请求初始化,脚本执行,请求关闭几个阶段,在SAPI关闭时,才经历模块关闭阶段以上是本文的全部内容,希望对大家的学习有帮助,也希望大家多多支持。
php自学中心 ,学习与交流少不了一个圈子,点击加技术群:PHP自学中心交流②群
亲爱的读者们,感谢您花时间阅读本文。如果您对本文有任何疑问或建议,请随时联系我。我非常乐意与您交流。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。