深入解析PHP底层机制及相关原理


Posted in PHP onDecember 11, 2020

1、PHP是什么? 

PHP 指的是我们从外面看到的一套完整的系统。这听起来有点糊涂,但其实并不复杂(PHP4 内部结构图)。从功能上来分:我们可以分为三部分:

1、 解释器部分(Zend 以引擎),负责对输入代码的分析、翻译和执行;

2、 功能性部分(PHP功能函数以及扩展),负责具体实现语言的各种功能(比如它的函数等等);

3、 接口部分(SAPI),负责同 WEB 服务器的会话等功能。 Zend包括了第一部分的全部和第二部分的局部,PHP内核 包括了第二部分的局部和第三部分的全部。他们合起来称之为 PHP 包。Zend 构成了语言的核心,同时也包含了一些最基本的 PHP 预定义函数的实现。PHP 包(内核)则包含了所有创造出语言本身各种显著特性的模块。 

               深入解析PHP底层机制及相关原理

                                                                                                    (PHP 内部结构图)

 从内容模块上来分:我们可以分为四层体系结构:

1)Zend引擎:Zend整体用纯c实现,是php的内核部分,它将php代码翻译(词法、语法解析等一系列编译过程)为可执行opcode的处理并实现相应的处理方法、实现了基本的数据结构(如hashtable、oo)、内存分配及管理、提供了相应的api方法供外部调用,是一切的核心,所有的外围功能均围绕zend实现。

2)Extensions扩展:围绕着zend引擎,extensions通过组件式的方式提供各种基础服务,我们常见的各种内置函数(如array系列)、标准库等都是通过extension来实现,用户也可以根据需要实现自己的extension以达到功能扩展、性能优化等目的(如贴吧正在使用的php中间层、富文本解析就是extension的典型应用)。

3)Sapi :Sapi全称是Server Application Programming Interface,也就是服务端应用编程接口,sapi通过一系列钩子函数,使得php可以和外围交互数据,这是php非常优雅和成功的一个设计,通过sapi成功的将php本身和上层应用解耦隔离,php可以不再考虑如何针对不同应用进行兼容,而应用本身也可以针对自己的特点实现不同的处理方式。

4)上层应用: 这就是我们平时编写的php程序,通过不同的sapi方式得到各种各样的应用模式,如通过webserver实现web应用、在命令行下以脚本方式运行等等。

          深入解析PHP底层机制及相关原理

                                                                              (php结构 )

其架构思想:引擎(Zend)+扩展(ext)的模式:降低内部耦合

中间层(sapi):web server和php的通信接口, 隔绝web server和php。

如果php是一辆车,那么

车的框架就是php本身,即是我们外面看到一套完整系统。

Zend是车的引擎(发动机)

Ext下面的各种组件就是车的轮子

Sapi可以看做是公路,车可以跑在不同类型的公路上

而一次php程序的执行就是汽车跑在公路上。

因此,我们需要:性能优异的引擎+合适的车轮+正确的跑道

2、php生命周期

      查看:深入理解php底层:php生命周期 :http://blog.csdn.net/hguisu/article/details/7377520

3 、sapi

如前所述,sapi通过通过一系列的接口,使得外部应用可以和php交换数据并可以根据不同应用特点实现特定的处理方法,我们常见的一些sapi有:

1) 、apache2handler :这是以apache作为webserver,采用mod_php模式运行时候的处理方式,也是现在应用最广泛的一种。

2)、cgi :这是webserver和php直接的另一种交互方式,也就是大名鼎鼎的fastcgi协议,在最近今年fastcgi+php得到越来越多的应用,也是异步webserver所唯一支持的方式。

3)、cli :命令行调用的应用模式

如图:Sapi的简单示意图

深入解析PHP底层机制及相关原理

 Sapi的定义及主要接口函数:

struct _sapi_module_struct { char *name; // 名字标识 char *pretty_name; // 更好理解的名字 int (*startup)(struct _sapi_module_struct *sapi_module); // 启动函数 int (*shutdown)(struct _sapi_module_struct *sapi_module); // 关闭方法 int (*activate)(TSRMLS_D); //激活 int (*deactivate)(TSRMLS_D); // 停用 int (*ub_write)(const char *str, unsigned int str_length TSRMLS_DC); // 没有缓存的写操作(unbuffered write) void (*flush)(void *server_context); // flush struct stat *(*get_stat)(TSRMLS_D); // get uid char *(*getenv)(char *name, size_t name_len TSRMLS_DC); // getenv void (*sapi_error)(int type, const char *error_msg, ...); /* error handler */ int (*header_handler)(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC); /* header handler */ /* send headers handler */ int (*send_headers)(sapi_headers_struct *sapi_headers TSRMLS_DC); void (*send_header)(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC); /* send header handler */ int (*read_post)(char *buffer, uint count_bytes TSRMLS_DC); /* read POST data */ char *(*read_cookies)(TSRMLS_D); /* read Cookies */ /* register server variables */ void (*register_server_variables)(zval *track_vars_array TSRMLS_DC); void (*log_message)(char *message); /* Log message */ time_t (*get_request_time)(TSRMLS_D); /* Request Time */ void (*terminate_process)(TSRMLS_D); /* Child Terminate */ char *php_ini_path_override; //覆盖ini路径 ... ...};

这里介绍一下其中一些主要函数

· startup:php被调用时初始化操作,比如cgi模式,在startup的时候会加载所有的extension并执行模块初始化工作。

· shutdown:php关闭时收尾工作

· activate:请求初始化

· dectivate:请求结束时收尾工作

· ub_write:指定数据输出方式,比如apache2handler方式,由于php作为apache的一个so存在,因此其输出也就是调 用apache的ap_write函数,而在cgi模式下,会系统调用write。

·  sapi_error:错误处理函数

·  read_post:读取post数据

·  register_server_variables:往$_SERVER中注册环境变量这个一般根据不同协议标准注册注册的变量。

在php源码中,sapi实现了很多接口:如下图:

深入解析PHP底层机制及相关原理

4、php脚本的执行

SAPI处于PHP架构的上层,而真正的脚本执行是有Zend引擎来完成。

目前语言分为两类:

第一类:编译型语言.如c/c++ java之类,他们的共性是运行之前必须对源代码进行编译,然后运行编译后的目标文件。

第二类语言:解释型语言:如PHP,Ruby,Python。他们需要解释器来执行这些源代码。实际上这些语言还是要经过编译环节的。只不过他们在运行的时候进行编译,为了效率,并不是每次执行的时候都会重新编译,比如PHP的各种opcode缓存扩展(如APC Xcache等)。

说明:PHP从2000年发布的PHP4开始就不是解释性语言。当一个PHP脚本被执行的时候,首先PHP源代码由Zend引擎编译成名为Zend opcodes的机器代码。这些代码保存在RAM中。然后执行opcodes运行真正的脚本。因此,PHP实际上和Java,C#等语言一样是编译语言。否则,它的执行会很慢。

我们来看PHP脚本是怎么被执行的。如hello.php:

<?php$str = "Hello world!\n";echo $str;

命令行执行:php hello.php

输出结果显然是:Hello world!

但是执行脚本的时候,PHP/Zend做了什么呢?

4.1、程序的执行:

1)传递给php程序需要的执行文件hello.php,php程序完成基本的准备工作后启动PHP及Zend引擎,加载注册的扩展模块。

2) 初始化完后读取脚本文件,Zend引擎对脚本进行此词法分析,语法分析,然后有Zend引擎编译成opcode码,最后执行 opcode码。

php代码的执行过程如下图:

                           深入解析PHP底层机制及相关原理

php实现了一个典型的动态语言执行过程:拿到一段代码后,经过词法解析、语法解析等阶段后,源程序会被翻译成一个个指令(opcodes),然后ZEND虚拟机顺次执行这些指令完成操作。PHP本身是用c实现的,因此最终调用的也都是c的函数,实际上,我们可以把php看做是一个c开发的软件。

通过上面描述不难看出,php的执行的核心是翻译出来的一条一条指令,也即opcode.

4.2、词法分析和语法分析

解释器一般包括两部分:

1)、 读取源程序,并处理语言结构

2)、处于语言结构并生成目标程序

而Lex和Yacc可以解决第一个问题。很多编程都有Lex/Yacc作为语言的词法语法分析生成器,比如PHP,Python、Ruby已经MySql的sql语言。

Lex生成词法分析器。

Yacc语法分析生成器

4. 3、opcode

PHP 构建在Zend虚拟机(Zend VM)之上的,PHP的opcode就是ZEND 虚拟机中的指令,即Opcode是php程序执行的最基本单位。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
PHP+MYSQL的文章管理系统(一)
Oct 09 PHP
PHP EOT定界符的使用详解
Sep 30 PHP
php去掉字符串的最后一个字符附substr()的用法
Mar 23 PHP
通过table标签,PHP输出EXCEL的实现方法
Jul 24 PHP
php 发送带附件邮件示例
Jan 23 PHP
php5.2以下版本无json_decode函数的解决方法
May 25 PHP
PHP对象递归引用造成内存泄漏分析
Aug 28 PHP
PHP实现动态执行代码的方法
Mar 25 PHP
PHP实现自动识别原编码并对字符串进行编码转换的方法
Jul 13 PHP
php5.3后静态绑定用法详解
Nov 11 PHP
php实现评论回复删除功能
May 23 PHP
PHP实现双链表删除与插入节点的方法示例
Nov 11 PHP
基于PHP实现发微博动态代码实例
Dec 11 #PHP
PHP isset empty函数相关面试题及解析
Dec 11 #PHP
PHP数组实际占用内存大小原理解析
Dec 11 #PHP
PHP基于ip2long实现IP转换整形
Dec 11 #PHP
PHP哈希表实现算法原理解析
Dec 11 #PHP
PHP解决高并发的优化方案实例
Dec 10 #PHP
WordPress伪静态规则设置代码实例
Dec 10 #PHP
You might like
PHP array操作10个小技巧分享
2011/06/23 PHP
PHP中改变图片的尺寸大小的代码
2011/07/17 PHP
php的ajax简单实例
2014/02/27 PHP
php中时间函数date及常用的时间计算
2017/05/12 PHP
详解php伪造Referer请求反盗链资源
2019/01/24 PHP
jQuery的实现原理的模拟代码 -4 重要的扩展函数 extend
2010/08/03 Javascript
使用Math.floor与Math.random取随机整数的方法详解
2013/05/07 Javascript
JS对话框_JS模态对话框showModalDialog用法总结
2014/01/11 Javascript
JavaScript实现点击按钮就复制当前网址
2015/12/14 Javascript
jQuery+Pdo编写login登陆界面
2016/08/01 Javascript
原生js实现轮播图
2017/02/27 Javascript
React 组件间的通信示例
2018/06/14 Javascript
谈谈JavaScript中super(props)的重要性
2019/02/12 Javascript
vue实现局部刷新的实现示例
2019/04/16 Javascript
JS实现简单省市二级联动
2019/11/27 Javascript
小程序如何写动态标签的实现方法
2020/02/05 Javascript
ES6中new Function()语法及应用实例分析
2020/02/19 Javascript
JavaScript代码简化技巧实例解析
2020/09/09 Javascript
[08:08]DOTA2-DPC中国联赛2月28日Recap集锦
2021/03/11 DOTA
python分析网页上所有超链接的方法
2015/05/08 Python
python 读取txt中每行数据,并且保存到excel中的实例
2018/04/29 Python
Dlib+OpenCV深度学习人脸识别的方法示例
2019/05/14 Python
python实现连续变量最优分箱详解--CART算法
2019/11/22 Python
使用Python制作一个数据预处理小工具(多种操作一键完成)
2021/02/07 Python
如何在Canvas上的图形/图像绑定事件监听的实现
2020/09/16 HTML / CSS
html5跳转小程序wx-open-launch-weapp踩坑
2020/12/02 HTML / CSS
英国建筑用品在线:Building Supplies Online(BSO)
2018/04/30 全球购物
德国苹果商店:MacTrade
2020/05/18 全球购物
Currentbody德国站:健康与美容技术专家
2020/04/05 全球购物
妇联主席先进事迹
2014/05/18 职场文书
竞选班干部演讲稿500字
2014/08/20 职场文书
2014年学校团委工作总结
2014/12/20 职场文书
2015年环卫工作总结
2015/04/28 职场文书
个人落户申请书怎么写?
2019/06/28 职场文书
导游词之张家口
2019/12/13 职场文书
PostgreSQL之连接失败的问题及解决
2023/05/08 PostgreSQL