2011-06-04 36 views
10

如果isset()empty()都生成完全相同的ISSET_ISEMPTY_DIM_OBJ操作碼,那麼PHP虛擬機如何分辨兩者之間的區別?isset()和empty()如何使用相同的操作碼?

此代碼:

empty($a['b']); 
isset($a['b']); 

產生以下的操作碼:

ISSET_ISEMPTY_DIM_OBJ $a, b -> TMP_VAR 0 
FREE TMP_VAR 0 

ISSET_ISEMPTY_DIM_OBJ $a, b -> TMP_VAR 1 
FREE TMP_VAR 1 

另一個測試:

if (empty($a['b'])) { 
    echo 'abc'; 
} 

if (isset($a['b'])) { 
    echo 'abc'; 
} 

這產生:

ISSET_ISEMPTY_DIM_OBJ $a, b -> TMP_VAR 0 
JMPZ TMP_VAR 0, &(BC4E00+4) 
ECHO abc 
JMP &(BC4E00+4) 

ISSET_ISEMPTY_DIM_OBJ $a, b -> TMP_VAR 1 
JMPZ TMP_VAR 1, &(BC4FE0+8) 
ECHO abc 
JMP &(BC4FE0+8) 
+3

你怎麼會得到這個級別大聲笑 – dynamic 2011-06-04 15:51:42

+0

這可能是一些優化的結果。你沒有使用返回值。嘗試更復雜的東西,比如「if(...)」。 – Gumbo 2011-06-04 15:55:19

+0

@Gumbo,更新了問題。 – rid 2011-06-04 16:26:33

回答

5

無論你用什麼工具創建操作碼轉儲,它只告訴你一半的事實:它忘記提及PHP傳遞一個常量到該操作碼,具體取決於使用哪種語言結構。那些常數是ZEND_ISEMPTY(對於emptyZEND_ISSET)對於isset

您可以找到調用herehere。 (和here類型被放入操作碼的extended_value。)

如果你看一下full opcodes,你會看到那些常量1ext列(ZEND_ISSET = (1<<0))和2ZEND_ISEMPTY = (1<<1))。

+0

聽起來很合理。 – GolezTrol 2011-06-17 22:16:44

4

你是如何得到這些操作碼的?

我使用「Bytekit」跑了您的代碼段,並得到了以下的輸出:

Function:   main 
Number of oplines: 5 
Compiled variables: !0 = $a 

    line #  opcode       result operands 
    ----------------------------------------------------------------------------- 
    3  0  ISEMPTY_DIM_OBJ     ~0  !0, 'b' 
     1  FREE          ~0 
    4  2  ISSET_DIM_OBJ     ~1  !0, 'b' 
     3  FREE          ~1 
    6  4  RETURN         1 

所以,在這種情況下,存在操作碼的差異。 唯一的問題是,我似乎無法在官方PHP網站上找到'我的'操作碼。這種困惑我,因爲bytekit已被證明是迄今爲止一個很好的工具。

我會研究一下,但在此期間,我想,您可能會發現我的當前任何值的輸出。

順便說一下,我在PHP上運行5.3.3的PHP。

+0

它必須是因爲PHP版本。我正在使用PHP 5.3.4。 – rid 2011-06-04 16:20:03

相關問題