PHP中的opcode

来源:互联网 发布:mysql truncate 编辑:程序博客网 时间:2024/06/10 23:38



opcodephp语言里供zend引擎执行的一种中间代码,类似java中的字节码、或者python中的字节码对象pycodeobject.


对于如下的一段php代码


<?php

echo “Hello World”;

$a = $a + 1;

echo $a;


和传统的编译流程一样,zend引擎在执行这段代码之前,首先会进行词法及语法的分析。词法分析就是将代码识别成一个个的token,对于上边的代码,php词法分析的结果如下:

[

    [

        379, //token idT_OPEN_TAG,可参考token_name(379)的返回结果

        "<?php\n", //具体的token

        1 //行号

    ],

    [

        382, //T_WHITESPACE

        "\t",

        2

    ],

    [

        328,

        "echo",

        2

    ],

    [

        382,

        " ",

        2

    ],

    [

        319,

        "\u201cHello",

        2

    ],

    [

        382,

        " ",

        2

    ],

    [

        319,

        "World\u201d",

        2

    ],

    ";",

    [

        382,

        "\n\t",

        2

    ],

    [

        320,

        "$a",

        3

    ],

    [

        382,

        " ",

        3

    ],

    "=",

    [

        382,

        " ",

        3

    ],

    [

        320,

        "$a",

        3

    ],

    [

        382,

        " ",

        3

    ],

    "+",

    [

        382,

        " ",

        3

    ],

    [

        317,

        "1",

        3

    ],

    ";",

    [

        382,

        "\n\t",

        3

    ],

    [

        328,

        "echo",

        4

    ],

    [

        382,

        " ",

        4

    ],

    [

        320,

        "$a",

        4

    ],

    ";",

    [

        382,

        "\n\n",

        4

    ]

]


可以看到,识别的结果是一个个的token array,每个token array的第一元素是zend引擎中定义的token id,第二个元素是具体的token,第三个是在源码中的行号。


php的词法及语法分析都是基于开源的lex yac工具,在语法分析阶段,php根据定义的形式语言描述验证给定的代码是否符合php语言语法规范,并在此过程中生成对应的opcodeopcode列表参考:http://php.net/manual/en/internals2.opcodes.php


安装vld之后,即可通过php -dvld.active=1 test.php查看对应的opcode,如下

Finding entry points

Branch analysis from position: 0

Jump found. (Code = 62) Position 1 = -2

function name:  (null)

number of ops:  6

compiled vars:  !0 = $a

line     #* E I O op                           fetch          ext  return  operands

-------------------------------------------------------------------------------------

   2     0  E >   ECHO                                                     'Hello+World'

   3     1        ASSIGN                                                   !0, 1

   4     2        ADD                                              ~2      !0, 1

         3        ASSIGN                                                   !0, ~2

   5     4        ECHO                                                     !0

   7     5      > RETURN                                                   1


branch: #  0; line:     2-    7; sop:     0; eop:     5; out1:  -2

path #1: 0, 


opcode可能包含如下字段:

1line:在源码中的行号

2)#:opcode编号

3op:名称

4fetch

5ext:与该opcode关联的额外数据,如跳转的目标opcode

6return:返回值存储的问题

7operands:操作数








原创粉丝点击