Categories: PHP编程

PHP代码是如何执行的

当我们执行一段PHP代码时,会发生很多事情。一般来说,PHP解释器在执行代码时会经历四个阶段:

  1. 词法分析
  2. 解析
  3. 编译
  4. 解释

词法分析

词法分析(或令牌化)是将字符串(本例中是PHP源代码)转换为令牌序列的过程。令牌只是它所匹配的值的命名标识符。PHP使用re2c从zend_language_scanner生成lexer。

$code = <<<'code'
<?php
$a = 1;
code;

$tokens = token_get_all($code);

foreach ($tokens as $token) {
    if (is_array($token)) {
        echo "Line {$token[2]}: ", token_name($token[0]), " ('{$token[1]}')", PHP_EOL;
    } else {
        var_dump($token);
    }
}

输出:

Line 1: T_OPEN_TAG ('<?php
')
Line 2: T_VARIABLE ('$a')
Line 2: T_WHITESPACE (' ')
string(1) "="
Line 2: T_WHITESPACE (' ')
Line 2: T_LNUMBER ('1')
string(1) ";"

上面的输出中有几个值得注意的地方。第一点是,并不是所有的源代码片段都被命名为标记。相反,有些符号被认为是它们自身的标志(例如=、;、:、?等)。第二点是lexer实际上比简单地输出一个标记流要多做一点。在大多数情况下,它还存储词素(由标记匹配的值)和匹配标记的行号(用于堆栈跟踪之类的事情)。

解析

解析器也是通过BNF语法文件与Bison一起生成的。PHP使用LALR(1)(向前看,从左到右)上下文无关的语法。前瞻性部分仅仅意味着解析器能够提前查看n个标记(在本例中为1个),以解决解析过程中可能遇到的歧义。从左到右的部分意味着它从左到右解析标记流。

生成的解析器阶段将来自lexer的标记流作为输入,并有两个作业。它首先通过尝试根据其BNF语法文件中定义的任何语法规则匹配令牌顺序来验证令牌顺序的有效性。这确保了有效的语言结构是由令牌流中的令牌组成的。解析器的第二项工作是生成抽象语法树(AST)——将在下一阶段(编译)中使用的源代码的树视图。

我们可以使用php-ast扩展查看解析器生成的AST的形式。内部AST没有直接公开,因为它不是特别“干净”(就一致性和一般可用性而言),所以php-ast扩展对它进行了一些转换,使它更易于使用。

编译

编译阶段使用AST,通过递归遍历树来发出操作码。此阶段还执行一些优化。这包括用文字参数解析一些函数调用(如strlen("abc")来整型(3))和折叠常数数学表达式(如60 60 24来整型(86400))。

在这个阶段,我们可以通过多种方式检查操作码输出,包括OPcache、VLD和PHPDBG。我将使用VLD实现这一点,因为我觉得输出看起来更友好。

解释

最后一个阶段是操作码的解释。这是在Zend引擎(ZE) VM上运行操作码的地方。实际上,关于这个阶段(至少从高层次的角度来看)几乎没什么可说的。输出几乎与您的PHP脚本通过echo、print、var_dump等命令输出的内容相同。

因此,在这个阶段,我们不需要深入研究任何复杂的东西,这里有一个有趣的事实:在生成自己的VM时,PHP需要自己作为一个依赖项。这是因为VM是由PHP脚本生成的,因为它更易于编写和维护。

5.0
01
tcpdump工具
PHP是编译型还是解释型?
嘻嘻

嘻嘻IT: 笔者是一个工作七八年的程序猿老鸟,从事涉及的技术栈主要包括PHP、Linux、Devops等,喜欢研究新技术,尝试新技术,提升技术自动化和开发效率,致力于write less,do more! 技术每年都会层出不穷,领域划分的越来越细,不可能学习所有的东西,保持对技术的好奇心,理解技术中核心思想,做一个有深度,有思想的开发!

Share
Published by
嘻嘻

Recent Posts

全球货币导航网页上线了!

o在全球化的今天,货币兑换和国…

2小时 ago

bash字符串拼接

在编程中,字符串的拼接是一个非…

3小时 ago

Bash Case详解

Bash case 语句通常用…

3小时 ago

Bash for详解

for循环是编程语言中的基础概…

3小时 ago

liunux中你必须知道alias命令?

在Linux操作系统中,无论你…

23小时 ago

zshrc文件详解

Zsh 是一个强大的 shel…

2天 ago