【问题标题】:"Undefined variable" when used after assignment in an if-clause在 if 子句中赋值后使用“未定义变量”
【发布时间】:2014-10-04 01:04:55
【问题描述】:

if (true && 1 == $x = 1 && $x) { echo "Hello world!"; }

我收到 $x 的未定义变量通知。解析器此时不应该知道 $x,因为它从左到右解决了 If-Clause 吗?

【问题讨论】:

  • 为什么要投反对票?
  • 是的,我可以接受。但我真的很想知道答案
  • 为什么投反对票?因为您在问我们“此时此变量是否应该已经存在”,同时给我们 zero 方法来了解一种或另一种方式,并发布一个清楚该基本缺陷的问题,简单明了。 ||为什么 投反对票?因为我写的东西,尽管有人假设,但不是真的:你的代码很难阅读和理解,几乎每个遇到它的人都会假设我开始这个评论的内容。重写它。
  • 对不起。我认为它是可读的。我将使用 user2864740 编写的示例对其进行编辑

标签: php variables expression conditional-statements


【解决方案1】:

观察到的行为取决于表达式的解析方式。以下

if (1 == $x = 1 && $x) {
    echo "Hello world!";
}

导致“未定义的变量:x”并且回显,但是

if (1 == ($x = 1) && $x) {
    echo "Hello world!";
}

“工作”并按预期发出 Hello world!

这是因为前者等价于

if (1 == ($x = (1 && $x))) {
    echo "Hello world!";
}

$x 的使用是 inside 将用于赋值的表达式。由于这是在赋值生效之前评估的,因此根据 PHP,$x 仍然是一个“未定义的变量”。

解决方案:

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

虽然operator precedence 是主要的替罪羊,但第一种形式等同于(1 == $x) = (1 && $x),后者是直接遵循优先级表时的推导。如果以这种方式解析它会导致“语法错误,=意外”。

这种解析是 PHP 的一个怪癖,与 C 语法规则不同。 (PHP的YACC规则可以在zend_language_parser.y找到。)

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

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

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

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

【讨论】:

  • 该死,我以为它会从左到右解析,就像它也从左到右解决 if 子句一样。谢谢你:)
  • 不是解析,是operator precedence
  • @user2864740,在计算机语言解析之前确实存在运算符优先级。
  • @Sorin Parser:“解析器是一个软件组件,它接受输入数据(通常是文本)并构建数据结构——通常是某种解析树、抽象语法树或其他层次结构——给出输入的结构表示,检查过程中的语法是否正确。”
  • @Sorin 我不相信该表中给出的运算符优先级准确地解释了这个问题。我已经添加了一个反对这样的论点。
猜你喜欢
  • 2020-08-31
  • 1970-01-01
  • 2021-08-13
  • 2017-08-09
  • 2017-03-21
  • 2011-02-15
  • 1970-01-01
  • 2020-06-27
  • 1970-01-01
相关资源
最近更新 更多