2012-07-23 53 views
8

我想了解簡單代碼的操作代碼。在if語句中理解PHP操作代碼

的代碼是:

<?php 

$a = TRUE; 

$b = FALSE; 

if($a && $b) { 
    echo 'done'; 
} 

上面的代碼,操作碼:

php -dvld.active=1 test.php 
Finding entry points 
Branch analysis from position: 0 
Jump found. Position 1 = 3, Position 2 = 4 
Branch analysis from position: 3 
Jump found. Position 1 = 5, Position 2 = 7 
Branch analysis from position: 5 
Jump found. Position 1 = 7 
Branch analysis from position: 7 
Return found 
Branch analysis from position: 7 
Branch analysis from position: 4 
filename:  /home/starlays/learning/test.php 
function name: (null) 
number of ops: 8 
compiled vars: !0 = $a, !1 = $b 
line  # * op       fetch   ext return operands 
--------------------------------------------------------------------------------- 
    3  0 > ASSIGN             !0, true 
    5  1  ASSIGN             !1, false 
    7  2 > JMPZ_EX           ~2  !0, ->4 
     3 > BOOL            ~2  !1 
     4 > > JMPZ              ~2, ->7 
    8  5 > ECHO              'done' 
    9  6 > JMP              ->7 
    10  7 > > RETURN             1 

branch: # 0; line:  3- 7; sop:  0; eop:  2; out1: 3; out2: 4 
branch: # 3; line:  7- 7; sop:  3; eop:  3; out1: 4 
branch: # 4; line:  7- 7; sop:  4; eop:  4; out1: 5; out2: 7 
branch: # 5; line:  8- 9; sop:  5; eop:  6; out1: 7 
branch: # 7; line: 10- 10; sop:  7; eop:  7 
path #1: 0, 3, 4, 5, 7, 
path #2: 0, 3, 4, 7, 
path #3: 0, 4, 5, 7, 
path #4: 0, 4, 7, 

我想了解什麼是第7行發生的事情,怎麼評價呢?它在評估的if表達式中輸入了多少個值?它輸入3個值,或者它輸入2個值$ a的值和$ b的值,然後if後面的括號中的表達式被評估?

我已閱讀JMPZ_EX的手冊,我已經理解操作代碼中發生了什麼,直到第2步之後有點混淆,並且我很難理解什麼是PHP的確切步驟這樣做。

我需要了解的另一件事是操作代碼中的所有分支是什麼,所有分支中的哪些分支將在最後被使用?

+0

'&&'是一個短路操作符。 – 2012-07-23 08:07:46

+0

@KarolyHorvath,我知道,我需要了解從上面的操作代碼的PHP的步驟。 – Starlays 2012-07-23 08:30:29

+0

我只是說你已經知道它應該如何表現,所以... – 2012-07-23 09:06:57

回答

2

除非你是精通ASM,我認爲最簡單的方法來了解正在發生的事情是通過閱讀它的(幾乎)1在看相同的代碼:在PHP 1只表示:

if(!$a) goto end; 
if(!$b) goto end; 
echo 'done'; 
end: return 0; 

中間表示是基於否定您的實際條款來跳過if塊中包含的代碼。

如果您想真正理解PHP如何將其輸入轉換爲此操作碼數組,您將不得不學習PHP內部知識,但不要在學習the dragon book之前學習,特別是關於中間表示的部分,它是編譯流水線的一部分。

其餘的操作碼是「背景噪音」,中間值,或甚至一個指令,這是沒有意義的9 6 > JMP ->7只是存在可能是因爲它沒有任何意義的努力,使PHP解析器吐出ZendVM運行的最佳操作碼數組。

2
line  # * op       fetch   ext return operands 
--------------------------------------------------------------------------------- 
    3  0 > ASSIGN             !0, true 
    5  1  ASSIGN             !1, false 
    7  2 > JMPZ_EX           ~2  !0, ->4 
     3 > BOOL            ~2  !1 
     4 > > JMPZ              ~2, ->7 
    8  5 > ECHO              'done' 
    9  6 > JMP              ->7 
    10  7 > > RETURN             1 

,打算到行號

0 assigns true to !0, !0 is just the internal representation of $A 
1 assigns true to !1, !1 is $B 

JMPZ意味着跳轉到代碼,如果該值爲0。我不知道JMPZ_EX的具體區別,它看起來像它允許返回一個布爾結果。

所以:

2 JMPZ_EX, Jump to #4 (->4) if !0 ($A) is 0 (FALSE) and assign the result to ~2 

3 BOOL !1 return ~2. ~2 is now equal to the BOOLean value of !1 ($B) 
4 JMPZ ~2, Jump to #7 if ~2 is zero 

5 ECHO, our echo statement. If any of the JMPZ had jumped, this part would be skipped. 
6 JMP -7, jumps to #7 
7 RETURN, ends the function call 

一些注意事項:

  • 這似乎是JMPZ_EX在這種情況下沒有必要的,但如果你需要語句中使用的值將是更加複雜有用計算更多值。
  • 6 JMP -7可能在那裏允許一個else塊。如果這是if塊的主要部分,那麼完成它可以跳過else塊的代碼部分。