php 代码 => token => 抽象语法树 => opcodes => 执行
各个步骤内容如下:
源代码通过词法分析得到 token
token 是 php 代码被切割成的有意义的标识。php7 一共有 137 种 token,在 zend_language_parser.h 文件中做了定义。
基于语法分析器将 token 转换成抽象语法树(ast)
token 就是一个个的词块,但是单独的词块不能表达完整的语义,还需要借助一定的规则进行组织串联。所以就需要语法分析器根据语法匹配 token,将 token 进行串联。语法分析器串联完 token 后的产物就是抽象语法树(ast,abstract syntax tree)。
ast 是 php7 版本的新特性,之前版本的 php 代码的执行过程中是没有生成 ast 这一步的。它的作用主要是实现了 php 编译器和解释器的解耦,提升了可维护性。
将语法树转换成 opcode
需要将语法树转换成 opcode,才能被引擎直接执行。
执行 opcodes
opcodes 是 opcode 的集合形式,是 php 执行过程中的中间代码。php 工程优化措施中有一个比较常见的 “开启 opcache”,指的技术这里将 opcodes 进行缓存。通过省去从源码到 opcode 的阶段,引擎直接执行缓存好的 opacode,以提升性能。
php7 内核架构
zend 引擎
词法 / 语法分析、ast 编译和 opcodes 的执行均在 zend 引擎中实现。此外,php 的变量设计、内存管理、进程管理等也在引擎层实现。
php 层
zend 引擎为 php 提供基础能力,而来自外部的交互则需要通过 php 层来处理。
sapi
server api 的缩写,其中包含了场景的 cli sapi 和 fpm sapi。只要遵守定义好的 sapi 协议,外部模块便可与 php 完成交互。
扩展部分
依据 zend 引擎提供的核心能力和接口规范,可以进行开发扩展。
php 7 源码结构
php 7 的源码主要目录有:sapi 、zend、main、ext 和 tsrm 这几个。
sapi 目录
sapi 目录是对输入和输出层的抽象,是 php 提供对外服务的规范。
几种常用的 sapi:
1)apache2handler: apache 扩展,编译后生成动态链接库,配置到 apache 下。当有 http 请求到 apache 时,根据配置会调用此动态链接库来执行 php 代码,完成与 php 的交互。
2)cgi-fcgi: 编译后生成支持 cgi 协议的可执行程序,webserver(如 nginx)通过 cgi 协议把请求传给 cgi 进程,cgi 进程根据请求执行相应代码后将执行结果返回给 webserver。
3)fpm-fcgi: fpm 是 fastcgi 进程管理器。以 nginx 服务器为例,当有请求发送到 nginx 服务器,nginx 按照 fastcgi 协议把请求交给 php-fpm 进程处理。
4)cli: php 的命令行交互接口
zend 目录
zend 目录是 php 的核心代码。php 中的内存管理,垃圾回收、进程管理、变量、数组实现等均在该目录的源码里。
main 目录
main 目录是 sapi 层和 zend 层的黏合剂。zend 层实现了 php 脚本的编译和执行,sapi 层实现了输入和输出的抽象,main 目录则在它们中间起着承上启下的作用。承上,解析 sapi 的请求,分析要执行的脚本文件和参数;启下,调用 zend 引擎之前,完成必要的模块初始化等工作。
ext 目录
ext 是 php 扩展相关的目录,常用的 array、str、pdo 等系列函数都在这里定义。
tsrm
tsrm(thread safe resource manager)—— 线程安全资源管理器, 是用来保证资源共享的安全。
以上就是php7的执行过程你了解吗?的详细内容。