为什么isset()和empty()都使用相同的操作码?

时间:2011-06-04 14:47:59

标签: php

如果isset()empty()生成完全相同的ISSET_ISEMPTY_DIM_OBJ操作码,那么PHP VM如何区分这两者?

此代码:

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)

2 个答案:

答案 0 :(得分:5)

无论你使用什么工具来创建操作码转储,它只告诉你一半的事实:它忘了提到PHP正在向该操作码传递一个常量,具体取决于使用的语言结构。这些常量ZEND_ISEMPTYemptyZEND_ISSETisset

您可以找到调用herehere。 (并here将类型放入操作码的extended_value。)

如果查看full opcodes,您会在{{1 ZEND_ISSET = (1<<0)2)和ZEND_ISEMPTY = (1<<1)ext)中看到这些常量1}}列。

答案 1 :(得分: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已被证明是一个很好的工具。

我会调查一下,但与此同时,我想,你可能会发现我目前输出的任何价值。

顺便说一句,我是在Ubuntu上运行5.3.3的PHP。