if (true && 1 == $x = 1 && $x) {
echo "Hello world!";
}
我收到$ x的未定义变量通知。解析器此时不应该知道$ x,因为它从左到右解决了If-Clause?
答案 0 :(得分:1)
观察到的行为是由于解析表达式的方式。以下
if (1 == $x = 1 && $x) {
echo "Hello world!";
}
产生“Undefined variable:x”并且不回显,但是
if (1 == ($x = 1) && $x) {
echo "Hello world!";
}
“正常”并按预期发出 Hello world!。
这是因为前者相当于
if (1 == ($x = (1 && $x))) {
echo "Hello world!";
}
并且$ x的使用 将用于赋值的表达式。由于在赋值生效之前对它进行了求值,因此根据PHP,$ x仍然是一个“未定义的变量”。
解决方案:
虽然operator precedence是主要的替罪羊,但第一种形式是而不是等同于(1 == $x) = (1 && $x)
,这是直接跟随优先表时的推导。如果以这种方式解析它会导致“语法错误,=意外”。
这种解析是PHP的一个怪癖,与C语法规则不同。 (可以在zend_language_parser.y中找到PHP的YACC规则。)
PHP:1 && $x = 2
- > 1 && ($x = 2)
,按照上述等效性。即使&&
声称具有更高的优先级,也会发生这种情况。
C:1 && x = 2
- > (1 && x) = 2
,语法无效:“左值作为赋值的左操作数”。在C中,&&
运算符在表达式中确实具有更高的优先级。
将&&
替换为==
时,同样的行为很明显:尽管分配的文档优先级较低,但当赋值是表达式的一部分时,简单优先级表会产生误导和不准确。
总之, $x = expr
作为表达式的一部分被等效地解析为($x = (expr))
,其中expr
本身就是一个复杂的包含运算符和其他表达式的表达式。