Tianji's Blog.

php-项目结构

Word count: 1,050 / Reading time: 4 min
2018/09/26 Share

整体结构

首先使用tree -L 1 -d来看一下所有目录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
qianfa@qianfa:~/Desktop/php_debug/php-7.0.12$ tree -L 1 -d
.
├── build
├── ext
├── include
├── libs
├── main
├── modules
├── netware
├── pear
├── sapi
├── scripts
├── tests
├── travis
├── TSRM
├── win32
└── Zend
目录 描述
TSRM 线程相关安全的实现
Zend PHP解析器的核心实现
build linux下编译相关的目录
ext PHP的扩展
main PHP的主要代码
netware 网络目录,socket的定义与实现
pear PHP扩展及应用的代码仓库
sapi PHP的应用层接口
scripts Linux下的脚本目录
tests 测试脚本目录
travis 用于构建,非PHP特有目录
win32 Windows下编译PHP的相关脚本
modules 仅有opcache.a和opcache.so
libs 目录为空
include 目录为空

核心目录主要包括sapi,main,zend,ext,TSRM,也是需要重点关注目录。

php整体架构图如下:

sapi(Server API)

我们知道,php执行的方法有多种,常见的比如cli模式,fpm/cgi模式,apache2handler模式,除此以外还有embed模式,litespeed模式,这两种没怎么用过。

1
2
3
4
5
6
7
8
9
10
qianfa@qianfa:~/Desktop/php_debug/php-7.0.12/sapi$ tree -L 1
.
├── apache2handler
├── cgi
├── cli
├── embed
├── fpm
├── litespeed
├── phpdbg
└── tests

SAPI则负责PHP对外提供服务的规范,它定义了结构体sapi_module_struct,该结构体定义了模式启动,关闭,激活,失效等多个钩子函数指针,每个模式将这些函数指针指向自己的函数,从而可以轻松扩展PHP对外服务的方式。

当需要调用服务器相关信息时,全部通过SAPI接口中对应方法调用实现,而这对应的方法在各个服务器抽象层实现时都会有各自的实现。此外,由于很多操作的通用性,有很大一部分的接口方法使用的是默认方法。

调用示意图如下:

main

php的核心文件所在,主要实现PHP的基本设施,承接SAPI的请求,分析出要执行的脚本文件和参数,并对环境和配置进行初始化,比如初始化变量和常量、注册函数、解析配置文件、加载扩展等等。

参考示意图:

Zend

Zend引擎的实现目录,主要负责PHP的语法实现、内存管理及脚本的编译运行环境,opcode的执行以及扩展机制的实现等,它由编译器、执行器两部分组成。Zend引擎类似于Java虚拟机,opcode则类似于java字节码。

编译器负责将PHP代码进行词法、语法分析,并生成抽象语法树,然后进一步编译为opcode,opcode是Zend虚拟机可识别的指令,php7一共有173个opcode,所有的语法都是由这些opcode组成的。执行器负责执行编译器输出的opcode。

ext(extension)

官方扩展目录,它是扩展PHP内核功能的一种方式,分为PHP扩展与zend扩展,都支持用户自定义开发,这两种都比较常见,PHP扩展有gd、json、date、array等,而我们熟知的opcache就是Zend扩展。其中包括了绝大多数PHP的函数的定义和实现,如array系列,pdo系列,spl系列等函数的实现,都在这个目录中。个人写的扩展在测试时也可以放到这个目录,方便测试和调试。

TSRM(hread Safe Resource Manager)

线程安全资源管理器。PHP的线程安全是构建在TSRM库之上的,PHP实现中常见的*G宏通常是对TSRM的封装。

全局变量就是定义在函数外的变量,它属于公共资源,在多线程的环境下,访问公共资源就可能会引起冲突,TSRM就是为解决该问题而诞生的。它为每个线程分配一个独立的自增ID,该ID作为当前线程的全局变量内存区的索引,从而实现线程的完全独立。

其实PHP大部分SAPI都是单线程的,所以并不需要过多关注线程安全,但是在Apache或者用户自己实现的PHP环境下,就需要考虑线程安全问题了。

参考链接:

CATALOG
  1. 1. 整体结构
  2. 2. sapi(Server API)
  3. 3. main
  4. 4. Zend
  5. 5. ext(extension)
  6. 6. TSRM(hread Safe Resource Manager)
  7. 7. 参考链接: