PHP从入门到精通(第7版)
上QQ阅读APP看书,第一时间看更新

1.2 PHP 8的执行原理

首先我们来学习几个关键术语。

1.Token

Token是PHP代码被切割成的有意义的标识。PHP提供了token_get_all()函数来获取PHP代码被切割后的Token。二维数组的每个成员数组的第一个值为Token对应的枚举值,第二个值为Token对应的原始字符串内容,第三个值为代码对应的行号,可见Token就是一个个的“词块”。但是单独存在的词块不能表达完整的语义,还需要借助规则进行组织串联。语法分析器就是这个组织者,它会检查语法,匹配Token,并对Token进行关联。

2.AST

抽象语法树(简称AST)是PHP 7版本的新特性。在这之前的版本中,PHP代码的执行过程中是没有生成AST这一步的。AST的结点分为多种类型,对应着PHP语法。通常使用PHP-Parser工具查看PHP代码生成的AST。注意,PHP-Parser是《PHP 7内核》作者之一Nikic编写的将PHP源码生成AST的工具,其源码参见https://github.com/nikic/PHP-Parser。

3.opcodes

opcode只是单条指令,opcodes是opcode的集合形式,是PHP执行过程中的中间代码。opcode生成之后,由虚拟机执行。PHP工程优化措施中有一个比较常见的“开启opcache”,指的就是这里的opcodes的缓存(opcodes cache)。通过省去从源码到opcode的阶段,引擎可以直接执行缓存的opcode,以此提升性能。借助vld插件,可以直观地看到一段PHP代码生成的opcode。opcode是PHP 7定义的一组指令标识,指令对应着相应的handler(处理函数)。当虚拟机调用opcode时,会找到opcode背后的处理函数,执行真正的处理程序。

了解以上几个术语知识后,我们来看PHP的执行原理。

在PHP 5中,从PHP脚本到opcodes的执行过程如下。

(1)词法分析。源代码首先进行词法分析,切割为多个字符串单元,得到Token。

(2)语法分析。独立的Token无法表达完整语义,因此需经过语法分析,将Token转换为opcodes。

在PHP 7和PHP 8中,执行原理如图1.3所示。

(1)词法分析。源代码首先进行词法分析,切割为多个字符串单元,得到Token。

(2)语法分析。独立的Token无法表达完整语义,因此需经过语法分析,将Token转换为AST。

(3)编译。抽象语法树被转换为机器指令并执行。在PHP中,这些指令被称为opcode,由PHP解释执行。

图1.3 PHP 7、PHP 8的执行原理