如果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)
答案 0 :(得分:5)
无论你使用什么工具来创建操作码转储,它只告诉你一半的事实:它忘了提到PHP正在向该操作码传递一个常量,具体取决于使用的语言结构。这些常量ZEND_ISEMPTY
为empty
,ZEND_ISSET
为isset
。
您可以找到调用here和here。 (并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。