0

PHP的目录结构、设计理念以及核心架构

 2 years ago
source link: https://sunct.github.io/posts/67d3d9f2.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

PHP的目录结构、设计理念以及核心架构

前一节:使用ext_skel,实现一个PHP扩展,试着使用 ext_skel 写了一个扩展,通过上一节可以大体了解自己如何写一个扩展。这一节主要介绍一下PHP的目录结构、设计理念以及核心架构。

一、PHP的目录结构

PHP源代码还包括在开发过程中生成的几个文件,以及在上游各自位置进行维护的几个部分。(注:PHP版本7.4.13)

<php-src>/
├─ .git/ # Git configuration and source directory
├─ TSRM/ # Thread Safe Resource Manager
└─ Zend/ # Zend Engine
├─ zend_vm_execute.h # Generated by `Zend/zend_vm_gen.php`
├─ zend_vm_opcodes.c # Generated by `Zend/zend_vm_gen.php`
├─ zend_vm_opcodes.h # Generated by `Zend/zend_vm_gen.php`
└─ ...
├─ appveyor/ # Appveyor CI service files
└─ build/ # *nix build system files
├─ ax_*.m4 # https://github.com/autoconf-archive/autoconf-archive
├─ config.guess # https://git.savannah.gnu.org/cgit/config.git
├─ config.sub # https://git.savannah.gnu.org/cgit/config.git
├─ libtool.m4 # https://git.savannah.gnu.org/cgit/libtool.git
├─ ltmain.sh # https://git.savannah.gnu.org/cgit/libtool.git
├─ shtool # https://www.gnu.org/software/shtool/
└─ ...
├─ docs/ # PHP internals and repository documentation
└─ ext/ # PHP core extensions
└─ bcmath/
├─ libbcmath/ # Forked and maintained in php-src
└─ ...
└─ curl/
├─ sync-constants.php # The curl symbols checker
└─ ...
└─ date/
└─ lib/ # Bundled datetime library https://github.com/derickr/timelib
├─ parse_date.c # Generated by re2c 0.15.3
├─ parse_iso_intervals.c # Generated by re2c 0.15.3
└─ ...
└─ ...
└─ ffi/
├─ ffi_parser.c # Generated by https://github.com/dstogov/llk
└─ ...
└─ fileinfo/
├─ libmagic/ # Modified libmagic https://github.com/file/file
├─ data_file.c # Generated by `ext/fileinfo/create_data_file.php`
├─ libmagic.patch # Modifications patch from upstream libmagic
├─ magicdata.patch # Modifications patch from upstream libmagic
└─ ...
└─ gd/
├─ libgd/ # Bundled and modified GD library https://github.com/libgd/libgd
└─ ...
└─ mbstring/
├─ libmbfl/ # Forked and maintained in php-src
├─ unicode_data.h # Generated by `ext/mbstring/ucgendat/ucgendat.php`
└─ ...
└─ pcre/
├─ pcre2lib/ # https://www.pcre.org/
└─ ...
└─ pdo_mysql/
├─ php_pdo_mysql_sqlstate.h # Generated by `ext/pdo_mysql/get_error_codes.php`
└─ ...
└─ skeleton/ # Skeleton for developing new extensions with `ext/ext_skel.php`
└─ ...
└─ standard/
└─ html_tables/
├─ mappings/ # https://www.unicode.org/Public/MAPPINGS/
└─ ...
├─ credits_ext.h # Generated by `scripts/dev/credits`
├─ credits_sapi.h # Generated by `scripts/dev/credits`
├─ html_tables.h # Generated by `ext/standard/html_tables/html_table_gen.php`
└─ ...
└─ tokenizer/
├─ tokenizer_data.c # Generated by `ext/tokenizer/tokenizer_data_gen.sh`
└─ ...
└─ xmlrpc/
├─ libxmlrpc/ # Forked and maintained in php-src
└─ ...
└─ zend_test # For testing internal APIs. Not needed for regular builds.
└─ ...
└─ zip/ # Bundled https://github.com/pierrejoye/php_zip
└─ ...
└─ ...
└─ main/ # Binding that ties extensions, SAPIs, and engine together
├─ streams/ # Streams layer subsystem
├─ php_version.h # Generated by release managers using `configure`
└─ ...
├─ pear/ # PEAR installation
└─ sapi/ # PHP SAPI modules
└─ cli/
├─ mime_type_map.h # Generated by `sapi/cli/generate_mime_type_map.php`
└─ ...
└─ ...
├─ scripts/ # php-config, phpize and internal development scripts
├─ tests/ # Core features tests
├─ travis/ # Travis CI service files
└─ win32/ # Windows build system files
├─ cp_enc_map.c # Generated by `win32/cp_enc_map_gen.exe`
└─ ...
└─ ...
目录 说明
TSRM 线程相关安全的实现,PHP的线程安全是构建在TSRM库之上的,PHP实现中常见的*G宏通常是对TSRM的封装,TSRM(Thread Safe Resource Manager)线程安全资源管理器。
Zend PHP解析器的核心实现,比如脚本的词法语法解析,opcode的执行以及扩展机制的实现等
build linux下编译相关的目录
ext PHP的扩展,包括了绝大多数PHP的函数的定义和实现,如array系列,pdo系列,spl系列等函数的实现,都在这个目录中。个人写的扩展在测试时也可以放到这个目录,方便测试和调试。
main PHP的主要代码,这里存放PHP最为核心的文件,主要实现PHP的基本设施,这里和Zend引擎不一样,Zend引擎主要实现语言最核心的语言运行环境。
netware 网络目录,socket的定义与实现
pear PHP扩展及应用的代码仓库,包含PEAR的核心文件。PEAR是PHP扩展与应用库(the PHP Extension and Application Repository)的缩写。它是一个PHP扩展及应用的一个代码仓库,简单地说,PEAR之于PHP就像是CPAN(Comprehensive Perl Archive Network)之于Perl。
sapi PHP的应用层接口,包含了各种服务器抽象层的代码,例如apache的mod_php,cli,cgi,embed以及fpm等接口。
scripts Linux下的脚本目录
tests 测试脚本目录,包含PHP各项功能的测试文件
travis 用于构建,非PHP特有目录
win32 Windows下编译PHP的相关脚本,比如sokcet的实现在Windows下和*Nix平台就不太一样,同时也包括了Windows下编译PHP相关的脚本。

虽然源码目录众多,但是核心目录却只有sapi、main、zend、ext、TSRM。

1、SAPI

PHP程序的输入可以是来自于命令行的标准输入,也可以是来自基于cgi/fastcgi协议的网络请求。甚至可以嵌入到单片机供C、C++程序调用。它们分别对应cli模式、fpm/cgi模式、embed模式,除了这些还有apache2handler、litespeed模式。

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

同理,输出可以写到命令行的标准输出,也可以作为基于cgi/fastcgi协议的网络响应返回给客户端。

SAPI全称Server API,负责PHP对外提供服务规范,它定义了结构体sapi_module_struct,该结构体定义了模式启动、关闭、激活、失效等多个钩子函数指针,每个模式将这些函数指针指向自己的函数,就可以轻松扩展PHP对外服务的方式。以上几种模式也正是实现了sapi_module_strcut才完成了PHP的多场景应用。

几种常用的SAPI:

(1)、apache2handler:Apache扩展,编译后生成动态链接库,配置到Apache下,当有http请求到Apache时,根据配置会调用此动态链接库,执行PHP代码,完成与PHP的交互。

(2)、cgi-fcgi:编译后生成支持CGI协议的可执行程序,webserver(通常为Apache或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、main

main目录是SAPI层和Zend层的黏合剂。

main目录的作用是承接SAPI的请求,分析出要执行的脚本文件和参数,并对环境和配置进行初始化,比如初始化变量和常量、注册函数、解析配置文件、加载扩展等等。

3、Zend

Zend目录就是大家所熟知的Zend引擎,是PHP最核心的部分,主要负责PHP的语法实现、内存管理及脚本的编译运行环境等,它由编译器、执行器两部分组成。

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

4、ext

ext(extension),它是扩展PHP内核功能的一种方式,分为PHP扩展与zend扩展,都支持用户自定义开发,这两种都比较常见,PHP扩展有gd、json、date、array等,而我们熟知的opcache就是Zend扩展。

上一节使用ext_skel,实现一个PHP扩展 写的自定义扩展就放在此目录下。

5、TSRM

TSRM(Thread Safe Resource Manager)线程安全资源管理器。

全局变量就是定义在函数外的变量,它属于公共资源,在多线程的环境下,访问公共资源就可能会引起冲突,TSRM就是为解决该问题而诞生的。

线程安全机制主要为了保证共享资源的安全。PHP的线程安全机制简洁直观——在多线程环境下,为每个线程提供独立的全局变量副本。具体实施是通过TSRM为每个线程分配(分配前加锁)一个独立ID(自增)作为当前线程的全局变量内存区索引,在以后的全局变量访问中,实现线程之间的完全独立。

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

二、PHP的设计理念及特点

(1)、多进程模型:由于PHP是多进程模型,不同请求间互不干涉,这样保证了一个请求挂掉不会对全盘服务造成影响,目前PHP也早支持多线程模型。

(2)、弱类型语言:和C/C++、JAVA、C#等语言不同,PHP是一种弱类型的语言。一个变量的类型并不是一开始就确定不变的,运行中才会确定并可能发生隐式或显示的类型转换,这种机制的灵活性在web开发中非常方便、高效,具体会在后面PHP变量中详述。

(3)、引擎(Zend)+组件(ext)的模式降低内部耦合。

(4)、中间层(sapi )Sapi全称是Server Application Programming Interface 隔绝web server和PHP。

(5)、语法简单灵活,没有太多规范。缺点导致风格混杂。

三、PHP核心架构

Zend引擎中包含了编译器和解释器,从PHP代码到opcode的执行,均由Zend引擎完成。

Zend引擎除了实现了PHP的核心功能,还提供了一套接口,让PHP可以在更多的场景中使用,如命令行环境、Web环境等。

该架构图大致分为四大部分。

1、Zend引擎:前文介绍的词法/语法分析、AST编译和opcodes的执行均在Zend引擎中实现。此外,PHP的变量设计、内存管理、进程管理等也在引擎层实现。引擎为PHP提供了基础服务,PHP的可靠性和高性能都依赖引擎的基础支撑。同时,Zend引擎的可扩展性,还是PHP得以大规模应用的重要原因之一。

2、PHP层:Zend引擎为PHP提供基础能力(如内存分配和回收),而来自外部的交互则需要通过PHP层来处理。

3、SAPI:SAPI是Server API的缩写,其中包含了常见的cli SAPI和fpm SAPI。PHP定义好输入/输出规范,依据此规范与PHP交互的一方都可以称为Server。

4、扩展部分:Zend引擎提供了核心能力和接口规范。在此基础上开发的扩展,为PHP代码的性能和功能的多样性提供了更丰富的选项。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK