Php &引用;未定义变量";在if子句中的赋值后使用时

Php &引用;未定义变量";在if子句中的赋值后使用时,php,variables,expression,conditional-statements,Php,Variables,Expression,Conditional Statements,if(true&&1==x=1&&x){ 回声“你好,世界!”; } 我得到一个未定义的变量通知$x。解析器现在不应该知道$x吗,因为它从左到右求解If子句?观察到的行为是由于表达式的解析方式造成的。以下 if (1 == $x = 1 && $x) { echo "Hello world!"; } 结果为“未定义变量:x”,且不回显,但 if (1 == ($x = 1) && $x) { echo "Hello world!"; } “工作

if(true&&1==x=1&&x){
回声“你好,世界!”;
}


我得到一个未定义的变量通知$x。解析器现在不应该知道$x吗,因为它从左到右求解If子句?

观察到的行为是由于表达式的解析方式造成的。以下

if (1 == $x = 1 && $x) {
    echo "Hello world!";
}
结果为“未定义变量:x”,且不回显,但

if (1 == ($x = 1) && $x) {
    echo "Hello world!";
}
“工作”并发出你好世界!正如所料

这是因为前者相当于

if (1 == ($x = (1 && $x))) {
    echo "Hello world!";
}
$x的用法在将用于赋值的表达式中。因为这是在赋值生效之前计算的,$x仍然是PHP中的“未定义变量”

解决方案:

  • 使用括号,如图所示;或者
  • 避免条件表达式中的变量赋值,这是我的建议

尽管第一种形式是主要的替罪羊,但它并不等同于
(1==$x)=(1&&$x)
,后者是直接遵循优先表的派生形式。如果以这种方式对其进行解析,将导致“语法错误,=意外”

这种解析是PHP的一个怪癖,不同于C语法规则。(PHP的YACC规则可在中找到。)

  • PHP:
    1&&$x=2
    ->
    1&&($x=2)
    ,根据上述等效性。即使声明
    &&
    具有更高的优先级,也会发生这种情况

  • C:
    1&&x=2
    ->
    (1&&x)=2
    ,无效语法:“赋值的左操作数需要左值”。在C语言中,
    &&
    运算符在表达式中确实具有更高的优先级

当用
=
替换
&&
时,同样的行为很明显:尽管赋值具有较低的记录优先级,但当赋值是表达式的一部分时,简单优先级表会产生误导和不准确


总之,
$x=expr
作为表达式的一部分被等效地解析为
($x=(expr))
,其中
expr
本身可以是一个包含运算符和其他表达式的复杂表达式。

为什么要投反对票?是的,我可以接受。但我真的很想知道答案为什么投票失败?因为你在问我们“这个变量在这一点上不应该已经存在”的同时,给我们零方法去知道一种或另一种方式,并且发布了一个问题,这个基本缺陷是清楚的、简单的和明显的为什么我没有投反对票?因为我写的东西,尽管有人认为是真的,但却不是真的:你的代码很难阅读和理解,几乎所有遇到它的人都会假设我在开始这篇评论时使用了什么。重写一下,对不起。我认为它是可读的。我将用user2864740Damn编写的示例对其进行编辑,我认为它将从左到右进行解析,就像它也从左到右解析if子句一样。谢谢:)它不是解析,它是@user2864740,在计算机语言解析之前确实存在运算符优先级。@Sorin:“解析器是一个接收输入数据(通常是文本)的软件组件。”并构建一个数据结构——通常是某种解析树、抽象语法树或其他层次结构——给出输入的结构表示,并在过程中检查语法是否正确。”@Sorin我不相信该表中给出的运算符优先级准确地解释了这一问题。我添加了一个反对这种做法的论点。