【PHP7源码学习】源码整体结构分析

本文将从整体上来介绍和分析下PHP7的源码结构

PHP7源码架构

提到PHP,就不得不提Zend引擎,就如JVM对于JAVA来说,下图就是PHP7源码架构图,可以看到Zend引擎在PHP源码架构中的重要位置,Zend引擎包含了编译器,解析器,执行器,内存管理,基本变量,从PHP代码到Opcode的执行,都是由Zend引擎来完成的。

【PHP7源码学习】源码整体结构分析_第1张图片
PHP7源码架构图

上图主要分为四大部分:

  1) "Zend引擎:" PHP中的词法/语法,AST(抽象语法树PHP7专有的)编译,Opcode的执行都是在Zend
  引擎中实现的。另外,PHP的变量设计,内容管理,进程管理,也都是在Zend引擎中实现的。引擎为PHP
  提供了基础服务,可靠性,可扩展,高性能的保障。
  2)"PHP层(PHP API & PHP Core):"Zend引擎为PHP提供基础服务能力(内存分配和回收),而来自
  外部的交互则需要通过PHP层来处理
  3) "SAPI:"SAPI是Server API的缩写,其中包含了常见的Cli和FPM。PHP只要定义好input/output
  协议规范,根据此规范跟PHP交互的一方一般都称之为Server。这样的好处就是Server方可以忽略PHP内
  部实现。只要遵守定义好的SAPI协议,便可以完成交互,极大的丰富了PHP支持的Server类型生态
  4)“扩展部分:” Zend引擎提供了核心能力和接口规范。 

PHP7源码结构

PHP7源码Github地址

【PHP7源码学习】源码整体结构分析_第2张图片
PHP7源码结构图

从上面2张图中可以看出来PHP7主要包含这些目录:sapi、Zend、main、ext、TSRM,下面会一一介绍

1.SAPI目录源码

SAPI目录是对输入和输出层的抽象,是PHP提供对外服务的规范。

PHP程序的输入可以是来自CLi的Stdin,也可以是来自fastcgi协议的网络请求,同理,输出可以写到CLi
的Stdout,也可以基于fastcgi协议的网络相应返回给客户端

另外PHP为支持多场景交互,为不同的场景模型编写独立的程序。
如:(1)命令行模型对应的二进制程序是bin/php 
    (2)CGI模式对应的二进制程序是bin/cig
    (3)FastCGI模式对应的二进制程序是sbin/php-fpm

同时,对多个模型抽象了相同的模板(源码为结构体sapi_module_struct),其定义了模式启动,关闭,
激活(处理请求前),失效(处理请求后)等多个钩子函数指针。每一个模式的函数指针都指向自己的函数
实现不同模式之间的处理输入,输出的差异化。

常见的SAPI有以下几种:
1). apache2handler: Apache扩展,编译后生成的动态链接库,现在基本都是nginx,所以简单提一下
2)cgi-fcgi:编译后生成支持CGI协议的可执行程序,webserver(Nginx)通过CGI协议把请求传给CGI
进程,指向代码将结果返回给webserver,推出进程
3)fpm-fcgi:fpm全称:FastCGI Process Manager,PHP官方提供的FastCGI进程管理器。以Nginx为
例,当有Http协议请求发送到Nginx服务器,Nginx会按照FastCGI协议把请求发送给php-fpm进程处理。
4)CLI: Command Line Interface,PHP的命令行交互接口模式。

2.Zend目录源码

Zend目录是PHP的核心代码。
1. 内存管理模块
PHP实现了自己的内存管理器。主要操作实现在zend_alloc_sizes.h、zend_alloc.h、zend_alloc.c
    1)zend_alloc_sizes.h:PHP的内存管理器实行分级管理。跟Redis的内存管理大致是一样的。
    即分配策略安全需要的大小分为三种规格,分配时会根据实际需要空间来选择对齐,再进行分配。规
    格等级从小到大分别为small,large,huge。该文件便定义了PHP内存分配的基本单位。
     (1)small内存小于3KB,当PHP申请的内存小于3KB字节,使用small分配策略。
     (2)large内存介于3KB到2M-4KB之间
     (3)huge内存大于2M-4KB

   2). zend_alloc.h:主要是一些内存操作函数的声明。PHP内存管理器是在C语言内存操作函数
       malloc()、free()等做了一层封装
   3). zend_alloc.c:定义了内存操作函数的实现以及PHP内存管理器的核心数据结构_zend_mm_heap
       等等。

2. 垃圾回收
   为了解决循环引用问题(PHP中数组,对象使用过程中),PHP引入了垃圾回收机制。PHP7垃圾回收的
   实现主要包含在源文件zend_gc.h和zend_gc.c中。后续会有章节进行详细分析

3. 数组实现
    数组是PHP中最重要,最常用的复杂数据类型之一。支撑数组的底层数据结构HashTable也经常出现在
    扩展开发中。
    PHP7数组的底层实现主要在zend_hash.c和zend_hash.h两个文件中实现。后续也会有章节进行详细
    分析

3.main目录源码

Zend层实现了PHP脚本的解析编译和执行,SAPI层实现输入和输出的抽象,main目录就起到了承上启下的
作用:承上,解析SAPI的请求,分析要执行的脚本文件和参数;启下,调用Zend引擎前,完成必要的初始
化工作。如模块初始化(php_module_startup())。上面SAPI目录提到的模式启动的钩子函数都会调用
这个API,再如脚本执行(php_execute_script()),它是执行php脚本的通用入口,这些都可以在main
目录中找到。

4.ext目录源码

ext是php扩展相关的目录,常用的array,str,pdo等等系列函数都定义在此处。后面会有章节详细介绍

5.TSRM目录源码

1. PHP在后期引入线程安全机制(ZTS:Zend Thread Safety)。而TSRM就是在这样的背景下诞生的。
2. TSRM是Thread Safe Resource Manager的缩写即线程安全资源管理器。PHP在编译的时候提供了选项
--enable-maintainer-zts,可以激活定义ZTS常量,以支持线程安全。
3. 线程安全机制主要为了保证共享资源的安全。PHP的线程安全机制在多线程环境下,为每个线程提供独
立的全局变量副本。具体实现是通过TSRM为每个线程分配(上锁)一个独立的自增ID作为当前线程的全局
变量内存区索引。在以后的全局变量访问中,实现线程之间的完全独立。

至此 整个PHP7源码结构分析到此结束,请期待后续的章节知识揭晓

你可能感兴趣的:(【PHP7源码学习】源码整体结构分析)