Почему оба 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.