Почему оба isset() и empty() используют один и тот же код операции?

Если оба 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)

Ответ 1

Независимо от того, какой инструмент вы использовали для создания этого дампа кода операции, он только сказал вам половину правды: он забыл упомянуть, что PHP передает константу этому коду операции в зависимости от того, какая языковая конструкция была использована. Эти константы ZEND_ISEMPTY для empty и ZEND_ISSET для isset.

Здесь вы можете найти здесь здесь и здесь. (И здесь тип помещается в extended_value кода операции.)

Если вы посмотрите на полные коды операций вы увидите эти константы как 1 (ZEND_ISSET = (1<<0)) и 2 (ZEND_ISEMPTY = (1<<1)) в столбце ext.

Ответ 2

Как вы получили эти коды операций?

Я запустил фрагмент кода с помощью 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

Итак, в этом случае существует разница в кодах операций. Единственное, что я не могу найти "мои" opcodes на официальном сайте PHP. Этот тип головоломок меня, потому что bytekit оказался отличным инструментом до сих пор.

Я рассмотрю это, но тем временем, я думал, вы можете найти мой текущий вывод любой ценности.

Кстати, я работаю на PHP 5.3.3 на Ubuntu.