PHP程序运行流程:词法分析(Lexing,Tokenizing,Scanning)

在不开启 Opcache 的情况下,PHP解释器在解释PHP脚本的时候,首先会经过词法分析(Lexing),而词法分析的具体实现就是将PHP代码转换成 Tokens,此过程成为 Lexing / Tokenizing / Scanning 。

那么 Tokens 是啥样的呢,Lex就是一个词法分析的依据表。 Zend/zend_language_scanner.c会根据Zend/zend_language_scanner.l (Lex文件),来输入的 PHP代码进行词法分析,从而得到一个一个的“词”,PHP4.2开始提供了一个函数叫token_get_all这个函数就可以将一段PHP代码 Scanning成Tokens;

token_get_all ( string $source ) : array

token_get_all() 解析提供的 source 源码字符,然后使用 Zend 引擎的语法分析器获取源码中的 PHP 语言的解析器代号

解析器代号列表见:https://www.php.net/manual/zh/tokens.php

token 代号是在zend引擎中定义的,php的词法分析都是基于开源的 lex 工具。

或者使用 token_name() 翻译获取这个代号的字符串表示。

示例:

<?php
$str = 
'<?php 
$a = "a";
$b = "b";
$c = "c";

echo $a, $b, $c;'
;

$tokens = token_get_all($str);
print_r($tokens);

打印结果

Array
(
    [0] => Array
        (
            [0] => 379
            [1] => <?php
            [2] => 1
        )

    [1] => Array
        (
            [0] => 382
            [1] =>

            [2] => 1
        )

    [2] => Array
        (
            [0] => 320
            [1] => $a
            [2] => 2
        )

    [3] => Array
        (
            [0] => 382
            [1] =>
            [2] => 2
        )

    [4] => =
    [5] => Array
        (
            [0] => 382
            [1] =>
            [2] => 2
        )

    [6] => Array
        (
            [0] => 323
            [1] => "a"
            [2] => 2
        )

    [7] => ;
    [8] => Array
        (
            [0] => 382
            [1] =>

            [2] => 2
        )

    [9] => Array
        (
            [0] => 320
            [1] => $b
            [2] => 3
        )

    [10] => Array
        (
            [0] => 382
            [1] =>
            [2] => 3
        )

    [11] => =
    [12] => Array
        (
            [0] => 382
            [1] =>
            [2] => 3
        )

    [13] => Array
        (
            [0] => 323
            [1] => "b"
            [2] => 3
        )

    [14] => ;
    [15] => Array
        (
            [0] => 382
            [1] =>

            [2] => 3
        )

    [16] => Array
        (
            [0] => 320
            [1] => $c
            [2] => 4
        )

    [17] => Array
        (
            [0] => 382
            [1] =>
            [2] => 4
        )

    [18] => =
    [19] => Array
        (
            [0] => 382
            [1] =>
            [2] => 4
        )

    [20] => Array
        (
            [0] => 323
            [1] => "c"
            [2] => 4
        )

    [21] => ;
    [22] => Array
        (
            [0] => 382
            [1] =>


            [2] => 4
        )

    [23] => Array
        (
            [0] => 328
            [1] => echo
            [2] => 6
        )

    [24] => Array
        (
            [0] => 382
            [1] =>
            [2] => 6
        )

    [25] => Array
        (
            [0] => 320
            [1] => $a
            [2] => 6
        )

    [26] => ,
    [27] => Array
        (
            [0] => 382
            [1] =>
            [2] => 6
        )

    [28] => Array
        (
            [0] => 320
            [1] => $b
            [2] => 6
        )

    [29] => ,
    [30] => Array
        (
            [0] => 382
            [1] =>
            [2] => 6
        )

    [31] => Array
        (
            [0] => 320
            [1] => $c
            [2] => 6
        )

    [32] => ;
)

表示这段代码可以解析出 33 个元素,每一个元素有三个属性,第一个为解析器代号,第二个为字面值,第三个为行号。

比如我们看到的下标为 31 的数组,其代号为 320, 使用 token_name(320)得到其代号名称为T_VARIABLE,去代号列表查看:
在这里插入图片描述
Tokens 可以用在代码压缩,将文件压缩到一行;还可以用在代码混淆,将变量名替换成难以辨别的每次,比如 $name --> $oo00oo,之前有见到过这样的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值