If both isset()
and empty()
generate the exact same ISSET_ISEMPTY_DIM_OBJ
opcode, how can the PHP VM tell the difference between the two?
This code:
empty($a['b']);
isset($a['b']);
produces the following opcodes:
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
Another test:
if (empty($a['b'])) {
echo 'abc';
}
if (isset($a['b'])) {
echo 'abc';
}
This produces:
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)
Whatever tool you were using to create that opcode dump, it only told you half the truth: It forgot to mention that PHP is passing a constant to that opcode depending on which language construct was used. Those constants are ZEND_ISEMPTY
for empty
and ZEND_ISSET
for isset
.
You can find the invocations here and here. (And here the type is put into the extended_value
of the opcode.)
If you look at the full opcodes, you'll see those constants as 1
(ZEND_ISSET = (1<<0)
) and 2
(ZEND_ISEMPTY = (1<<1)
) in the ext
column.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With