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