Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How come both isset() and empty() use the same opcode?

Tags:

php

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)
like image 435
rid Avatar asked Jun 04 '11 14:06

rid


1 Answers

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.

like image 141
NikiC Avatar answered Oct 02 '22 02:10

NikiC