PHP的构成及生命周期

一、PHP开源源代码下载地址:

https://github.com/php/php-src.git

 

二、PHP的构成

1、目录结构

2、目录分析

(1)sapi目录是PHP的应用接口层。

(2)main为php的主要代码,主要是输入/输出、Web通信、PHP框架的初始化操作等,比如fastcgi协议的解析、扩展的加载、PHP配置的解析等工作都是在这里完成的。

(3)Zend目录是PHP解析器的主要实现,即ZendVM,它是PHP语言的核心实现,PHP代码的解释、执行都是由Zend完成的。

(4)ext目录是PHP的扩展目录,比如php的curl扩展,gd库扩展、pdo扩展等都是在这里。

(5)TSRM目录为线程安全相关的实现。

(6)PHP各组成部分之间关系图:

 

3、SAPI

(1)PHP是一个脚本解析器,提供脚本的解析与执行。它的输入是普通的文本,然后由PHP解析器按照预先定义好的语法规则进行解析执行。我们可以在不同环境中应用这个解析器,比如命令行下、Web环境下、嵌入其他应用中使用。为此,PHP提供了一个SAPI层以适配不同的应用环境,SAPI可以认为是PHP的宿主环境。

(2)SAPI也是整个PHP框架最外层的一部分,它主要负责PHP框架的初始化工作。SAPI代码位于PHP源码的 /sapi 目录下,经常用到的两个SAPI是Cli和Fpm。

 

4、ZendVM

(1)ZendVM是一个虚拟的计算机,它介于PHP应用和实际计算机中间,我们编写的PHP代码就是被它解释执行的。ZendVM是PHP语言的核心实现,他主要由两部分组成:编译器和执行器。

(2)编译器负责将PHP解释为执行器可识别的指令,执行器负责执行编译器解释出的指令。

(3)ZendVM的角色等同于Java中的JVM,它们都是抽象出的虚拟计算机。

 

5、Extension

(1)扩展是PHP内核提供的一套用于扩充PHP功能的一种方式,PHP社区中有丰富的扩展可供使用,这些扩展为PHP提供了大量实用的功能,PHP中很多操作的函数都是通过扩展提供的。

(2)通过扩展,我们可以使用C/C++实现更强大的功能和更高的性能。扩展分为PHP扩展和Zend扩展,PHP扩展比较常见,而Zend扩展主要应用于ZendVM,我们所熟知的Opcache就是Zend扩展。

 

三、PHP生命周期

1、PHP的整个生命周期被划分为以下几个阶段:

(1)模块初始化阶段(module startup)

(2)请求初始化阶段(request startup)

(3)脚本执行阶段(execute sccript)

(4)请求关闭阶段(request shutdown)

(5)模块关闭阶段(module shutdown)

注:根据不同SAPI的实现,各阶段的执行情况会有一些差异,比如命令行模式下,每次执行一个脚本都会完成的经历这些阶段。而FastCgi模式下则在启动时执行一次模块初始化,然后各个请求只经历请求初始化,脚本执行,请求关闭几个阶段,在SAPI关闭时,才经历模块关闭阶段。

 

2、模块初始化阶段—分析

(1)这个阶段主要进行PHP框架和Zend引擎的初始化操作。该阶段的入口函数为php_module_startup()。这个阶段一般只在SAPI启动时执行一次,对于Fpm而言,就是在Fpm的master进程启动时执行的。

(2)该阶段的几个主要处理如下:

(3)激活SAPI:sapi_activate(),初始化请求信息SG(request_info)、设置读取POST请求的handle等。

(4)启动PHP输出:php_output_startup()

(5)初始化垃圾回收器:gc_globals_ctor(),并分配zend_gc_globals内存。

(6)启动Zend引擎:zend_startup(),主要操作包括

      (6.1)启动内存池 start_memory_manager()

      (6.2)设置一些util函数句柄,如zend_error_cb、zend_pringf、zend_write等。

      (6.3)设置Zend虚拟机编译、执行器的函数句柄zend_compile_file、zend_execute_ex、垃圾回收函数句柄gc_collect_cycles

       (6.4)分配函数符号表 方法符号表(function_table)、类符号表(class_table)、常量符号表(zend_constants)等,如果是多线程的话,还会分配编译器、执行器的全局变量。

       (6.5)注册Zend核心扩展:zend_startup_builtin_funtions(),这个扩展是内核提供的,该过程将注册Zend核心扩展提供的函数,如strlen、define、func_get_args、class_exists等。

       (6.6)注册Zend定义的标准常量:zend_register_standard_constants(),比如 E_ERROR、E_WARNING、E_ALL、TRUE、FALSE等。

       (6.7)注册$GLOBALS超全局变量的获取handle。

       (6.8)分配php.ini配置的存储符号表 EG(ini_directives)。

(7)注册PHP定义的常量:PHP_VERSION、PHP_ZTS、PHP_SAPI等。

(8)解析php.ini:解析完成后所有的php.ini配置保存在configuration_hash哈希表中。

(9)映射PHP、Zend核心的php.ini配置:根据解析出的php.ini,获取对应的配置值,将最终的配置插入EG(ini_directives)哈希表。

(10)注册用于获取$_GET、$_POST、$_COOKIE、$_SERVER、$_ENV、$_REQUEST、$_FILES变量的handle。

(11)注册静态编译的扩展:php_register_internal_extensions_func()。

(12)注册动态加载的扩展:php_init_register_extensions(),将php.ini中配置的扩展加载到PHP中。

(13)回调各扩展定义的module startup钩子函数,即通过PHP_MINIT_FUNCTION()定义的函数。

(14)注册php.ini中禁用的函数、类:disable_funstions、disable_classes。

 

3、请求初始化阶段—分析

该阶段是在请求处理前每一个请求都会经历的一个阶段。对于fpm而言,是在worker进程accept一个请求且获取、解析完请求数据后的一个阶段。该阶段的处理函数为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()

 

4、脚本执行阶段—分析

(1)该阶段包括PHP代码的编译、执行两个核心阶段,这也是Zend引擎最重要的功能。

(2)在编译阶段,PHP脚本将经历从PHP源代码到抽象语法树,再到opline指令的转化过程,最终生成的opline指令就是Zend引擎可识别的执行指令,这些指令被执行器执行,这就是PHP代码解释执行的过程。该阶段入口函数为php_execute_script()。

 

5、请求关闭阶段—分析

(1)该阶段将flush输出内容、发送HTTP应答header头、清理局部变量、关闭编译器、关闭执行器等。

(2)另外,在该阶段将回调各扩展的request shutdown钩子函数。

(3)该阶段与请求初始化阶段操作是相反的。

 

6、模块关闭阶段—分析

该阶段在SAPI关闭时执行,与模块初始化阶段对应,主要进行资源的清理、PHP各模块的关闭操作,同时将回调各扩展的 module shutdown 钩子函数。

 

注:免费领取阿里云产品优惠券:https://www.haveyb.com/aliyun

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/282164.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《Adobe After Effects CS6完全剖析》——动画:最重要的是关系

本节书摘来自异步社区《Adobe After Effects CS6完全剖析》一书中的第2章,动画:最重要的是关系,作者 【美】Mark Christiansen(马克克里斯琴森),译者 苗玉敏,郭圣路,曹玉臣&#xff…

Oracle即将发布的全新Java垃圾收集器 ZGC

Java 11的特性集合已经确定,其中包含了一些非常棒的特性。新版本提供了一个全新的垃圾回收器ZGC,它由甲骨文开发,承诺在TB级别的堆上实现非常低的停顿时间。在本文中,我们将介绍甲骨文开发ZGC的动机、ZGC的技术概览以及ZGC带来的一…

如何获取 OSS AccessKeyId、AccessKeySecret

开通阿里云oss:https://www.aliyun.com/product/oss 1、点击概览 — AccessKey 注:官方链接 2、出现下图,选择“开始使用子用户Access Key” 3、填写用户名,并点击确定 4、这时会给你的手机发送验证码确定是本人操作,…

【网络爬虫入门02】HTTP客户端库Requests的基本原理与基础应用

【网络爬虫入门02】HTTP客户端库Requests的基本原理与基础应用 广东职业技术学院 欧浩源 2017-10-15 1、引言 实现网络爬虫的第一步就是要建立网络连接并向服务器或网页等网络资源发起请求。urllib是目前最常用的做法,然而Requests会比urlib更加方便,能…

《零信任的基石:使用 SPIFFE 为基础设施创建通用身份》翻译电子书分享

国庆假期除了去浙江和安徽玩了一圈欣赏江南山水和徽派建筑之外,还抽空翻译了一本电子书。本书译自 Solving the Bottom Turtle — a SPIFFE Way to Establish Trust in Your Infrastructure via Universal Identity。你可以选择在线阅读(推荐&#xff09…

《Outlook时间整理术》一创建和使用自己的文件夹结构

本节书摘来异步社区《Outlook时间整理术》一书中的第1章,作者: 【德】Lothar Seiwert , Holger Woeltje 译者: 欧阳宇,更多章节内容可以访问云栖社区“异步社区”公众号查看。 创建和使用自己的文件夹结构 花费约两小时为电子邮件…

《实用软件架构:从系统环境到软件部署 》——2.4 架构视图与架构视点

本节书摘来自华章出版社《实用软件架构:从系统环境到软件部署》一书中的第2章,第2.4节,作者:[印]蒂拉克米特拉(Tilak Mitra)著,爱飞翔 译,更多章节内容可以访问云栖社区“华章计算机…

TCP:当初取代NCP,如今害怕被取代

我叫TCP(Transmission Control Protocol)也叫传输控制协议。不觉回忆1983年,亲手将NCP协议淘汰,取而代之的是我,成了火遍大江南北的网络红人之一。现如今,我感受到前所未有的恐惧,因为我一生的敌…

批处理中的IF详解

在CMD使用IF /?打开IF的系统帮助会发现IF有3种基本的用法! 第一种用法:IF [NOT] ERRORLEVEL number command 这种用法现在很少用了,因为它需要使用到CHOICE命令,这个命令现在被set /p代替了,它是判断CHOICE命令选择的选项的&…

fullcalendar 显示的时间间隔只有四十五分钟_【体能新视点】——女子篮球运动员比赛期间的心率、血乳酸浓度和时间运动分析...

女子篮球运动员比赛期间的心率、血乳酸浓度和时间-运动分析—摘要—本研究的目的是检验女子篮球运动员在比赛规则改变后的生理需求和运动模式。在九场正式比赛中,对九名大学代表队队员进行了研究。每场比赛都被录像以确定主要动作的频率,连续记录心率&am…

《JavaScript机器人编程指南》——1.2 NodeBot是什么,基本词汇还有哪些

本节书摘来异步社区《JavaScript机器人编程指南》一书中的第1章,第1.2节,作者:【美】Kassandra Perch(珀芝),更多章节内容可以访问云栖社区“异步社区”公众号查看。 1.2 NodeBot是什么,基本词…

解决在Python中使用Win32api报错的问题,No module named win32api

一、系统环境 操作系统: Win7 64位 Python:3.7.0 二、在使用import win32api时,报错:No module named win32api 网上查到有下面解决办法: 方法1:pip install pypiwin32或pip3 install pypiwin32 或 python -m pip install pypiwin…

《Python游戏编程入门》——1.2 初识Python

本节书摘来自异步社区《Python游戏编程入门》一书中的第1章,第1.2节,作者[美]Jonathan S. Harbour ,李强 译,更多章节内容可以访问云栖社区“异步社区”公众号查看。 1.2 初识Python Python既是一个软件工具包,也是一种…

大数据:Parquet文件存储格式

一、Parquet的组成 Parquet仅仅是一种存储格式,它是语言、平台无关的,并且不需要和任何一种数据处理框架绑定,目前能够和Parquet适配的组件包括下面这些,可以看出基本上通常使用的查询引擎和计算框架都已适配,并且可以…

“数据门”事件频发 如何避免人为因素导致数据泄露?

前段时间,某酒店集团数据泄露引起轩然大波,泄露的数据中包含了用户姓名、手机号、邮箱、号等多项信息。卖家对这个约5亿条数据打包出售价格为8比特币或520门罗币。而关于此次信息泄露事件的原因,目前尚未定论。据悉,由于集团某程序…

lamda获取参数集合去空_JAVA集合框架知识

1. Vector用法和ArrayList区别(1) Vector的特有方法有哪些?void addElement(E obj) 将指定的组件添加到此向量的末尾,将其大小增加1。(2) Vector与ArrayList的区别是什么?①Vector的add()方法是同步方法,ArrayList的add()方法是非…

Blazor学习之旅(2)第一个Blazor应用

【Blazor】| 总结/Edison Zhou大家好,我是Edison。最近在学习Blazor做全栈开发,因此根据老习惯,我会将我的学习过程记录下来,一来体系化整理,二来作为笔记供将来翻看。本篇我们来构建第一个Blazor Web应用,…

HTTP与服务器的四种交互方式

Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而H…

ubuntu 以太网已连接但是无法联网_工业以太网有多“牛X”?两个案例告诉你

现代生活中,工业以太网发挥的作用愈来愈重要。为增进大家对工业以太网的认识,本文将基于3方面介绍工业以太网:何为工业以太网物理层?工业以太网具有哪些优势?工业以太网两大方案介绍。如果你对工业以太网具有兴趣&…

http服务详解(1)——一次完整的http服务请求处理过程

前言:要熟练掌握一个服务,首先需要非常了解这个服务的工作过程,这篇就详细解释了http服务的请求处理过程。 一次完整的http请求处理过程 (1)流程图 (2)过程详解 0、DNS域名解析:递归…