深入解析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 相关文章推荐
建立文件交换功能的脚本(一)
Oct 09 PHP
使用php来实现网络服务
Sep 15 PHP
php实现rc4加密算法代码
Apr 25 PHP
深入解析PHP内存管理之谁动了我的内存
Jun 20 PHP
CodeIgniter生成网站sitemap地图的方法
Nov 13 PHP
PHP用星号隐藏部份用户名、身份证、IP、手机号等实例
Apr 08 PHP
ThinkPHP3.1之D方法实例详解
Jun 20 PHP
ThinkPHP通过AJAX返回JSON的两种实现方法
Dec 18 PHP
Laravel 5框架学习之Blade 简介
Apr 08 PHP
PHP也能干大事 随机函数
Apr 14 PHP
yii2中使用Active Record模式的方法
Jan 09 PHP
laravel执行php artisan migrate报错的解决方法
Oct 09 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上传文件中文文件名乱码的解决方法
2013/11/01 PHP
ThinkPHP使用UTFWry地址库进行IP定位实例
2014/04/01 PHP
php实现微信支付之现金红包
2018/05/30 PHP
Array对象方法参考
2006/10/03 Javascript
javascript 跳转代码集合
2009/12/03 Javascript
jquery ready函数源代码研究
2009/12/06 Javascript
JS正则中的RegExp对象对象
2012/11/07 Javascript
jquery设置text的值示例(设置文本框 DIV 表单值)
2014/01/06 Javascript
jQuery中queue()方法用法实例
2014/12/29 Javascript
jQuery实现文本框输入同步的方法
2015/06/20 Javascript
浅谈JS使用[ ]来访问对象属性
2016/09/21 Javascript
根据Bootstrap Paginator改写的js分页插件
2016/12/25 Javascript
详解Element 指令clickoutside源码分析
2019/02/15 Javascript
详解vue中使用protobuf踩坑记
2019/05/07 Javascript
iphone刘海屏页面适配方法
2019/05/07 Javascript
vue.js的简单自动求和计算实例
2019/11/08 Javascript
vue深度监听(监听对象和数组的改变)与立即执行监听实例
2020/09/04 Javascript
[01:27:43]VGJ.S vs TNC Supermajor 败者组 BO3 第三场 6.6
2018/06/07 DOTA
python多线程http下载实现示例
2013/12/30 Python
python k-近邻算法实例分享
2014/06/11 Python
python使用Queue在多个子进程间交换数据的方法
2015/04/18 Python
django-filter和普通查询的例子
2019/08/12 Python
pygame实现贪吃蛇游戏(上)
2019/10/29 Python
python分布式计算dispy的使用详解
2019/12/22 Python
python中return的返回和执行实例
2019/12/24 Python
关于python 跨域处理方式详解
2020/03/28 Python
django中related_name的用法说明
2020/05/20 Python
python 爬取腾讯视频评论的实现步骤
2021/02/18 Python
详解HTML5之pushstate、popstate操作history,无刷新改变当前url
2017/03/15 HTML / CSS
博朗(Braun)俄罗斯官方商店:德国小家电品牌
2019/09/24 全球购物
Zalando Lounge瑞士:时尚与生活方式购物俱乐部
2020/03/12 全球购物
创先争优活动党员公开承诺书
2014/08/29 职场文书
个人授权委托书
2014/09/15 职场文书
离婚协议书格式
2014/11/21 职场文书
区域经理岗位职责
2015/02/02 职场文书
Vue OpenLayer 为地图绘制风场效果
2022/04/24 Vue.js