PHP7的内核剖析

php7-internal

记录

3 PHP的相关组成

3.1 SAPI

php常见的四种运行模式

SAPI:Server Application Programming Interface 服务器端应用编程端口。它就是PHP与其它应用交互的接口,PHP脚本要执行有很多种方式,通过Web服务器,或者直接在命令行下,也可以嵌入在其他程序中。
SAPI提供了一个和外部通信的接口,常见的SAPI有:cgi 、fast-cgi、cli、isapi、apache 模块的 DLL

PHP本身可以理解为是一个库函数,提供语言的编译与执行服务,它有标准的输入、输出,而SAPI是PHP的接入层,它接收用户的请求,然后调用PHP内核提供的一些接口完成PHP脚本的执行,所以严格意义上讲SAPI并不算PHP内核的一部分。

PHP中常用的SAPI有cli、php-fpm,cli是命令行下执行PHP脚本的实现:bin/php script.php,它是单进程的,处理模型比较简单,而php-fpm相对比较复杂,它实现了网络处理模块,用于与web服务器交互。

CGI
CGI即通用网关接口(Common Gateway Interface),它是一段程序,通俗的讲CGI就象是一座桥,把网页和WEB服务器中的执行程序连接起来,它把HTML接收的指令传递给服务器的执 行程序,再把服务器执行程序的结果返还给HTML页。CGI 的跨平台性能极佳,几乎可以在任何操作系统上实现。
CGI方式在遇到连接请求(用户 请求)先要创建cgi的子进程,激活一个CGI进程,然后处理请求,处理完后结束这个子进程。这就是fork-and-execute模式。所以用cgi 方式的服务器有多少连接请求就会有多少cgi子进程,子进程反复加载是cgi性能低下的主要原因。都会当用户请求数量非常多时,会大量挤占系统的资源如内 存,CPU时间等,造成效能低下。

FastCGI
fast-cgi 是cgi的升级版本,FastCGI像是一个常驻(long-live)型的CGI,它可以一直执行着,只要激活后,不会每次都要花费时间去fork一 次。PHP使用PHP-FPM(FastCGI Process Manager),全称PHP FastCGI进程管理器进行管理。

FastCGI的工作原理:

Web Server启动时载入FastCGI进程管理器(IIS ISAPI或Apache Module)
FastCGI进程管理器自身初始化,启动多个CGI解释器进程(可见多个php-cgi)并等待来自Web Server的连接。
当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。Web server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi。
FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在Web Server中)的下一个连接。 在CGI模式中,php-cgi在此便退出了。

3.2 Zend引擎

Zend是PHP语言实现的最为重要的部分,是PHP最基础、最核心的部分,它的源码在/Zend目录下,PHP代码从编译到执行都是由Zend完成的,后面章节绝大部分的源码分析都是针对Zend的。Zend整体由两个部分组成:

编译器: 负责将PHP代码编译为抽象语法树,然后进一步编译为可执行的opcodes,这个过程相当于GCC的工作,编译器是一个语言实现的基础

执行器: 负责执行编译器输出的opcodes,也就是执行PHP脚本中编写的代码逻辑

FPM

fpm的实现就是创建一个master进程,在master进程中创建并监听socket,然后fork出多个子进程,这些子进程各自accept请求,子进程的处理非常简单,它在启动后阻塞在accept上,有请求到达后开始读取请求数据,读取完成后开始处理然后再返回,在这期间是不会接收其它请求的,也就是说fpm的子进程同时只能响应一个请求,只有把这个请求处理完成后才会accept下一个请求,这一点与nginx的事件驱动有很大的区别,nginx的子进程通过epoll管理套接字,如果一个请求数据还未发送完成则会处理下一个请求,即一个进程会同时连接多个请求,它是非阻塞的模型,只处理活跃的套接字。

fpm的master进程与worker进程之间不会直接进行通信,master通过共享内存获取worker进程的信息,比如worker进程当前状态、已处理请求数等,当master进程要杀掉一个worker进程时则通过发送信号的方式通知worker进程。

fpm可以同时监听多个端口,每个端口对应一个worker pool,而每个pool下对应多个worker进程,类似nginx中server概念。

PHP7 深入理解的更多相关文章

  1. php7深入理解匿名函数和回调函数

    匿名函数是没有名称的函数,可以将函数赋值给变量,再调用使用,回调函数是指作为一个参数值传值另外一个函数使用的函数. //匿名函数 没名称的函数 $a=function (){echo "ww ...

  2. 深入理解 PHP7 中全新的 zval 容器和引用计数机制

    深入理解 PHP7 中全新的 zval 容器和引用计数机制 最近在查阅 PHP7 垃圾回收的资料的时候,网上的一些代码示例在本地环境下运行时出现了不同的结果,使我一度非常迷惑. 仔细一想不难发现问题所 ...

  3. 跟厂长学PHP7内核(八):深入理解字符串的实现

    在前面大致预览了常用变量的结构之后,我们今天来仔细的剖析一下字符串的具体实现. 一.字符串的结构 struct _zend_string { zend_refcounted_h gc; /* 字符串类 ...

  4. 深入理解PHP7之zval

    PHP7已经发布, 如承诺, 我也要开始这个系列的文章的编写, 今天我想先和大家聊聊zval的变化. 在讲zval变化的之前我们先来看看zval在PHP5下面是什么样子 PHP5zval回顾在PHP5 ...

  5. php7新特性的理解和比较

    1. null合并运算符(??) ??语法: 如果变量存在且值不为NULL,它就会返回自身的值,否则返回它的第二个操作数. //php7以前 if判断 if(empty($_GET['param']) ...

  6. PHP7内核(八):深入理解字符串的实现

    在前面大致预览了常用变量的结构之后,我们今天来仔细的剖析一下字符串的具体实现. 一.字符串的结构 struct _zend_string { zend_refcounted_h gc; /* 字符串类 ...

  7. CentOS 7.1编译安装PHP7

    原文: https://typecodes.com/web/centos7compilephp7.html?utm_source=tuicool&utm_medium=referral 1 创 ...

  8. vagrant系列教程(三):vagrant搭建的php7环境(转)

    原文:http://blog.csdn.net/hel12he/article/details/51107236 前面已经把vagrant的基础知识已经基本过了一遍 了,相信只要按着教程来,你已经搭建 ...

  9. PHP7革新与性能优化

    有幸参与2015年的PHP技术峰会(PHPCON),听了鸟哥(惠新宸)的关于PHP7的新特性和性能优化的分享,一切都令人感到激动.鸟哥是国内最权威的PHP专家,他的分享有很多非常有价值的东西,我通过整 ...

随机推荐

  1. alert、confirm、prompt的区别

    我们在开发一些后台管理系统的时候,经常会用到一些弹出框,今天我们一起看一下吧: alert:仅仅是一个提示的作用,通知用户,会阻线程,alert后面的代码,在用户点击确认后仍然会照常执行. confi ...

  2. winfrom中上传文件保存在webFrom里面

    winfrom里面的代码 private void button1_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(text ...

  3. vue-wechat-title

    html中的title安装:npm install vue-wechat-title --save1.在mian.js中//网页titleimport VueTitle from 'vue-wecha ...

  4. python基础数据类型之字符串操作

    1.字符串切片ps:字符串是不可变的对象, 所以任何操作对原字符 是不会有任何影响的 s1 = "python最简洁" print(s1[0]) print(s1[1]) prin ...

  5. 原生js获取页面中所有checkbox

    var inputs = document.getElementsByTagName("input");//获取所有的input标签对象 var checkboxArray = [ ...

  6. Fiddler(一)

    Fiddler:学习scrapy,不只是满足于网页上爬去信息的成功乐趣,现在开始接触爬去手机信息了,不好解决,知道过程不会轻松,但自己想去尝试.QAQ 写这篇博客是基于以下的几位大神学习笔记,我只是做 ...

  7. composer安装教程(Linux版)

    composer 是款不错的工具,那么如何进行安装composer呢 如果您是linux系统或是mac系统 请先确定是否安装了curl linux安装curl   1 yum install -y c ...

  8. talent-aio源码阅读小记(二)

    我们上一篇提到了talent-aio的四类Task:DecodeRunnable.HandlerRunnable.SendRunnable.CloseRunnable,并且分析了这些task的基类Ab ...

  9. Wind Of Change

    Wind of change until the end  变革的风一直吹直至最后 You will see that I will be your friend 你会看见我成为你的朋友 If you ...

  10. Java-JNA使用心得2

    自5月初第一次尝试使用Java封装调用C的dll之后,已经先后经历了3次小项目了. 上月末是最近的一次项目实际,任务来的急时间又少,还好在加班加点后还是完成了任务,并把第二次没有实现的功能给实现了(C ...