不同版本的php,其Opcode是否不同?

PHP 5.4出來快半年了,最近才注意到一些套件似乎還沒完全跟上,舉三個有在用的extension為例… 看來,跟核心比較無關的stomp已經支援PHP 5.4(stable)。另外兩個和核心有關的,尚在beta…
  • APC(Alternative PHP Cache),目前版本為APC 3.1.13
    3.1.0 開始支援 PHP 5.4,目前尚為beta
  • VLD(Vulcan Logic Disassembler),目前版本為0.11.1
    0.11.0 開始支援 PHP 5.4,目前尚為beta
  • Stomp client extension,目前版本為1.0.4
    已經支援 PHP 5.4,並stable

不經也好奇PHP版本不同時,編譯出來的Opcode是否相同?於是用下面『簡單』的php程式作個小測試…
  1. <?php  
  2.   
  3. $temp = array(1, 2, 3, 4);  
  4. $count = count($temp);  
  5. for ($i = 0; $i < $count$i++) {  
  6.     echo $i , PHP_EOL;  
  7. }  
  8. var_dump($temp);  

VLD之前介紹如何使用vld)分別測試PHP5.2(PHP 5.2.17)、PHP5.3(PHP 5.3.16 )、PHP5.4(PHP 5.4.6 )三種版本。以上面程式跑出來的結果,PHP5.3、PHP5.4相同、PHP5.2和前兩者不同。PHP5.2的Opcode多了幾行。細看下,大概有如下的差異…
  1. PHP5.2取得constant(PHP_EOL)時,多了FETCH_CONSTANT動作 (PHP5.3以上,則是直接取得0A)
  2. 最後有ZEND_HANDLE_EXCEPTION

最後,則列出兩種的Opcode…

以下,為PHP 5.2.17 的Opcode

number of ops:  22
compiled vars:  !0 = $temp, !1 = $count, !2 = $i
line     # *  op                     fetch      ext  return  operands
-----------------------------------------------------------------------
   3     0  >   INIT_ARRAY                             ~0      1
         1      ADD_ARRAY_ELEMENT                      ~0      2
         2      ADD_ARRAY_ELEMENT                      ~0      3
         3      ADD_ARRAY_ELEMENT                      ~0      4
         4      ASSIGN                                         !0, ~0
   4     5      SEND_VAR                                       !0
         6      DO_FCALL                            1  $2      'count'
         7      ASSIGN                                         !1, $2
   5     8      ASSIGN                                         !2, 0
         9  >   IS_SMALLER                             ~5      !2, !1
        10    > JMPZNZ                              E          ~5, ->18
        11  >   POST_INC                               ~6      !2
        12      FREE                                           ~6
        13    > JMP                                            ->9
   6    14  >   ECHO                                           !2
        15      FETCH_CONSTANT                         ~7      'PHP_EOL'
        16      ECHO                                           ~7
   7    17    > JMP                                            ->11
   8    18  >   SEND_VAR                                       !0
        19      DO_FCALL                            1          'var_dump'
        20    > RETURN                                         1
        21*   > ZEND_HANDLE_EXCEPTION

以下,為PHP5.2(PHP 5.2.17)、PHP5.3(PHP 5.3.16 )的Opcode
number of ops:  20
compiled vars:  !0 = $temp, !1 = $count, !2 = $i
line     # *  op                   fetch        ext  return  operands
-----------------------------------------------------------------------
   3     0  >   INIT_ARRAY                             ~0      1
         1      ADD_ARRAY_ELEMENT                      ~0      2
         2      ADD_ARRAY_ELEMENT                      ~0      3
         3      ADD_ARRAY_ELEMENT                      ~0      4
         4      ASSIGN                                         !0, ~0
   4     5      SEND_VAR                                       !0
         6      DO_FCALL                            1  $2      'count'
         7      ASSIGN                                         !1, $2
   5     8      ASSIGN                                         !2, 0
         9  >   IS_SMALLER                             ~5      !2, !1
        10    > JMPZNZ                              E          ~5, ->17
        11  >   POST_INC                               ~6      !2
        12      FREE                                           ~6
        13    > JMP                                            ->9
   6    14  >   ECHO                                           !2
        15      ECHO                                           '%0A'
   7    16    > JMP                                            ->11
   8    17  >   SEND_VAR                                       !0
        18      DO_FCALL                            1          'var_dump'
        19    > RETURN                                         1

補充一下…
當主機有安裝、使用Xdebug時,產生的Opcode又多了不少…(多了EXT_STMT、EXT_FCALL_BEGIN、EXT_FCALL_END)這也說明了,為何線上環境,不適合安裝Xdebug

以下,為PHP 5.2.17+ Xdebug的Opcode
number of ops:  32
compiled vars:  !0 = $temp, !1 = $count, !2 = $i
line     # *  op                    fetch      ext  return  operands
----------------------------------------------------------------------
   3     0  >   EXT_STMT
         1      INIT_ARRAY                            ~0      1
         2      ADD_ARRAY_ELEMENT                     ~0      2
         3      ADD_ARRAY_ELEMENT                     ~0      3
         4      ADD_ARRAY_ELEMENT                     ~0      4
         5      ASSIGN                                        !0, ~0
   4     6      EXT_STMT
         7      EXT_FCALL_BEGIN
         8      SEND_VAR                                      !0
         9      DO_FCALL                           1  $2      'count'
        10      EXT_FCALL_END
        11      ASSIGN                                        !1, $2
   5    12      EXT_STMT
        13      ASSIGN                                        !2, 0
        14  >   IS_SMALLER                            ~5      !2, !1
        15      EXT_STMT
        16    > JMPZNZ                            14          ~5, ->25
        17  >   POST_INC                              ~6      !2
        18      FREE                                          ~6
        19    > JMP                                           ->14
   6    20  >   EXT_STMT
        21      ECHO                                          !2
        22      FETCH_CONSTANT                        ~7      'PHP_EOL'
        23      ECHO                                          ~7
   7    24    > JMP                                           ->17
   8    25  >   EXT_STMT
        26      EXT_FCALL_BEGIN
        27      SEND_VAR                                      !0
        28      DO_FCALL                           1          'var_dump'
        29      EXT_FCALL_END
        30    > RETURN                                        1
        31*   > ZEND_HANDLE_EXCEPTION

留言