深入解析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 相关文章推荐
第八节 访问方式 [8]
Oct 09 PHP
SSI指令
Nov 25 PHP
PHP date函数参数详解
Nov 27 PHP
php 多个submit提交表单 处理方法
Jul 07 PHP
在字符串指定位置插入一段字符串的php代码
Feb 16 PHP
PHP 删除文件与文件夹操作 unlink()与rmdir()这两个函数的使用
Jul 17 PHP
PHP时间戳与日期之间转换的实例介绍
Apr 19 PHP
$_GET['goods_id']+0 的使用详解
Jun 06 PHP
解析centos中Apache、php、mysql 默认安装路径
Jun 25 PHP
php数组查找函数总结
Nov 18 PHP
文件上传之SWFUpload插件(代码)
Jul 30 PHP
浅谈PHP中new self()和new static()的区别
Aug 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中关于抽象(abstract)类和抽象方法的问题分析
2014/01/03 PHP
Apache PHP MySql安装配置图文教程
2016/08/27 PHP
php操作xml并将其插入数据库的实现方法
2016/09/08 PHP
Laravel学习基础之migrate的使用教程
2017/10/11 PHP
php使用QueryList轻松采集js动态渲染页面方法
2018/09/11 PHP
Thinkphp 框架基础之入口文件功能、定义与用法分析
2020/04/27 PHP
Jquery 设置标题的自动翻转
2009/10/03 Javascript
jquery随机展示头像代码
2011/12/21 Javascript
onkeypress字符按键兼容所有浏览器使用介绍
2013/04/24 Javascript
文本框回车提交与禁止提交示例
2013/09/27 Javascript
Js实现滚动变色的文字效果
2014/06/16 Javascript
基于AngularJS实现页面滚动到底自动加载数据的功能
2015/10/16 Javascript
快速学习jQuery插件 jquery.validate.js表单验证插件使用方法
2015/12/01 Javascript
JavaScript动态创建form表单并提交的实现方法
2015/12/10 Javascript
Angular.js中ng-if、ng-show和ng-hide的区别介绍
2017/01/20 Javascript
js/jquery控制页面动态加载数据 滑动滚动条自动加载事件的方法
2017/02/08 Javascript
angular实现spa单页面应用实例
2017/07/10 Javascript
温故知新——JavaScript中的字符串连接问题最全总结(推荐)
2017/08/21 Javascript
javascript+jQuery实现360开机时间显示效果
2017/11/03 jQuery
JS Input里添加小图标的两种方法
2017/11/11 Javascript
jquery动态添加带有样式的HTML标签元素方法
2018/02/24 jQuery
Typescript的三种运行方式(小结)
2019/09/18 Javascript
vue 解决form表单提交但不跳转页面的问题
2019/10/30 Javascript
详解Python中的动态属性和特性
2018/04/07 Python
对python数据切割归并算法的实例讲解
2018/12/12 Python
使用Python制作表情包实现换脸功能
2019/07/19 Python
python yield关键词案例测试
2019/10/15 Python
python list数据等间隔抽取并新建list存储的例子
2019/11/27 Python
基于html5 DeviceOrientation 实现微信摇一摇功能
2015/09/25 HTML / CSS
详解android与HTML混合开发总结
2018/06/06 HTML / CSS
计算机专业个人求职自荐信
2013/09/21 职场文书
地方课程教学计划
2015/01/19 职场文书
护士自我推荐信范文
2015/03/24 职场文书
面试通知邮件
2015/04/20 职场文书
pytorch显存一直变大的解决方案
2021/04/08 Python
六个好看实用的 HTML + CSS 后台登录入口页面
2022/04/28 HTML / CSS