PHP7内核实现原理-基本架构

拓朴冰川
• 阅读 541

发展史

PHP 最早是由 Lerdorf 于 1995年,使用 Perl 语言,以 Personal Home Page Tools (PHP Tools) 的形式创建的,目的是为了方便记录个人网站的访客记录和支持留言本等功能,此时称为 PHP 1

后来越来越多的网站开始使用 PHP 并希望能提供更多的功能,之后 Lerdorf 将 PHP 开源,此时称为 PHP 2

1997 年两个以色列程序员 Zeev Suraski 和 Andi Gutmans 重写了 PHP 的解析器,并于 1998 年正发布,此为 PHP 3,并从此开始 PHP 改为 Hypertext Preprocessor,新版的解析器命名为 Zend Engine。Zend 的命名来自于两位作者的名字。

2000 年,以 Zend 1.0 为基础的 PHP 4 发布。2004 年,以 Zend 2.0 为基础的 PHP 5 发布,至此 PHP 支持了面向对象、PDO、命名空间等特性,性能方面也大幅提升。

2015 年 12 月 3 日 PHP 7 发布,重构了 PHP 中很多重要且常用的数据结构,内存占用得到显著优化,性能也得到了大幅提升。

PHP 的组成

  • SAPI:

    PHP 本身可以理解为一组库函数,而 SAPI 则是其接入层,应用程序通过调用 SAPI 来间接调用 PHP 的函数,类似于 Shell 与 Linux 内核的关系。严格来讲 SAPI 不算是 PHP 内核的一部分。

  • Zend 引擎:

    Zend 引擎是 PHP 和核心,是 PHP 最最基础的部分。Zend 分为两部分:

    • 编译器:将应用层的 PHP 代码编译为抽象语法树 AST,进一步编译为可执行的 opcodes 。
    • 执行器:负责执行 opcodes

示意图:

PHP7内核实现原理-基本架构

SAPI 介绍

SAPI 即 Server Application Programming Interface,是应用程序与 PHP 内核交互的一套 API 规范。常见的 SAPI 实现有:

  • Apache mod_php 模块:

    该模块实现 SAPI 规范,使得让 Apache 与 PHP 做交互。

  • FastCGI/FPM:

    一般配合 Nginx 服务器处理 web 请求。

  • cli:

    命令行中执行 PHP 。

上层应用与实现了 SAPI 的模块做交互,上下两层都遵循 SAPI 规范:

PHP7内核实现原理-基本架构

FPM(FastCGI Process Manager) 介绍

要了解 FPM,首先要了解 CGI,CGI (Common Gateway Interface)定义了 Web 服务器和应用程序交互的规范,FastCGI 是在其之上优化改进的结果,增加了worker 常驻等特性,不用每次都 fork 新的进程来处理请求。

FastCGI 采用多进程模型,与 web 服务器配合处理 web 请求。服务器负责处理解析网络请求,之后交给 FastCGI,FastCGI 将请求交给其管理的 worker pool,由具体一个 worker 来处理请求。

FastCGI 中的 master 进程通过共享内存的方式获取 worker 进程的状态,通过发送信号的方式管理 worker。

FastCGI 也是一种协议,而 FPM 则是实现了这种协议的进程管理器。

FPM 可以同时监听多个端口,一个端口对应一个 worker pool

PHP7内核实现原理-基本架构

FPM 配置,监听在 unix sock 上

; worker pool名称
[www]
user = www
group = www

; 配置worker pool接收FastCGI请求的地址
; 可以是ip:port 也可以是unix sock
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
;                            a specific port;
;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses
;                            (IPv6 and IPv4-mapped) on a specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /run/php7-cgi.sock

listen.owner = www
listen.group = www
listen.mode = 0660
pm = dynamic
pm.max_children = 20
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 20

Nginx 与 FPM 通过 unix sock 交互配置

server
{
    listen 80;
    server_name xxx.xxx.com;
    index index.html index.php;
    root  /home/xxx/public;

    location / {
        if (!-e $request_filename){
            rewrite ^/(.*) /index.php last;
        }
    }
    location ~ [^/]\.php(/|$)
    {
        try_files $uri =404;
                # Nginx 转发请求给 PHP
        fastcgi_pass  unix:/run/php7-cgi.sock;
        fastcgi_index index.php;
        include fastcgi.conf;
    }
}

PHP7内核实现原理-基本架构

FPM master 管理 worker 的几种方式:

  • static:初始化就固定 worker 数不变
  • dynamic:动态调整 worker 数量
  • ondemand:相当于懒加载,一开始不创建 worker,之后请求到来在创建。

本文由mdnice多平台发布

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Easter79 Easter79
3年前
sql注入
反引号是个比较特别的字符,下面记录下怎么利用0x00SQL注入反引号可利用在分隔符及注释作用,不过使用范围只于表名、数据库名、字段名、起别名这些场景,下面具体说下1)表名payload:select\from\users\whereuser\_id1limit0,1;!(https://o
Stella981 Stella981
3年前
Kerberos无约束委派的攻击和防御
 0x00前言简介当ActiveDirectory首次与Windows2000Server一起发布时,Microsoft就提供了一种简单的机制来支持用户通过Kerberos对Web服务器进行身份验证并需要授权用户更新后端数据库服务器上的记录的方案。这通常被称为Kerberosdoublehopissue(双跃点问题),
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
3年前
PHP7版本改动细节整理翻译完毕
自从鸟哥发布PHP7相关的版本以来,就一直关注PHP7的进展。PHP7是非常值得期待的一个版本,性能获得了极大的提升,语法也更加合理规范。最近就花了一些时间,整理翻译了PHP7版本的改动记录文件。主要包括了以下部分:  2非兼容性改动   2.1语言修改   2.1.1变量处理机制修改   2.1.2list
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
3年前
MySQL数据库InnoDB存储引擎Log漫游(1)
作者:宋利兵来源:MySQL代码研究(mysqlcode)0、导读本文介绍了InnoDB引擎如何利用UndoLog和RedoLog来保证事务的原子性、持久性原理,以及InnoDB引擎实现UndoLog和RedoLog的基本思路。00–UndoLogUndoLog是为了实现事务的原子性,
Wesley13 Wesley13
3年前
PHP的历史
PHP/FIPHP继承自一个老的工程,名叫PHP/FI。PHP/FI在1995年由RasmusLerdorf创建,最初只是一套简单的Perl脚本,用来跟踪访问他主页的人们的信息。它给这一套脚本取名为“PersonalHomePageTools”。随着更多功能需求的增加,Rasmus写了一个更大的C语言的实现,它可以
Stella981 Stella981
3年前
CSV (逗号分隔值文件格式)
逗号分隔值(CommaSeparatedValues,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含必须像二进制数字那样被解读的数据。CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号
Stella981 Stella981
3年前
Spring 学习笔记(一):Spring 入门
1Spring简介Spring是一个轻量级Java开发框架,最早由RodJohnson创建,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题,是一个分层的JavaSE/EEfullstack轻量级开源框架,为开发Java应用程序提供全面的基础架构支持。2Spring体系结构