JS 与 PHP:与逻辑或

2022-08-31 01:14:33

(PHP 具有 和 。JS 只有 .)||OR||

新浪网.根据MDN具有比更高的优先级。所以这不起作用:||=

a || a = 1;

因为它被评估为:

(a || a) = 1;

这将导致“分配中的左侧无效”。我理解这一点。这是有道理的。

菲律宾比索。根据 PHP.net 它对PHP的工作原理相同:在.但是,我一直在使用它:||=

$a || $a = 1;

为什么它在PHP中工作??最重要的是:PHP的优先级低于 ,所以这些不应该做同样的事情:OR=

$a || $a = 1;
$a OR $a = 1;

但他们确实...https://3v4l.org/UWXMd

我认为JS根据MDN的表工作,PHP的工作就像PHP的表一样,但PHP不应该像它那样工作。||OR||

这是另一个奇怪的PHP怪癖吗?

该手册还提到了这一点:

尽管 PHP 的优先级低于大多数其他运算符,但 PHP 仍将允许类似于以下内容的表达式:,在这种情况下,的返回值将放入 。=if (!$a = foo())foo()$a

优先级表规定 PHP 应该计算 ,这没有意义,应该失败,但 PHP 将其计算为 ,因为它喜欢异常。(!$a) = foo()!($a = foo())

后续问题:你认为这有什么作用?https://3v4l.org/3P2hN我不明白...我确实理解第二种和第三种情况(与),只是不理解第一种情况下发生的事情。if ( $d = $c && $e = $b && $f = $a )and


答案 1

根据zend_language_parser.y,代码的解析分别等效于和在每种情况下。$a || ($a = 1)$a or ($a = 1)

正如melpomene所总结的那样,赋值生产不是表达式上的中缀二元运算符;相反,分配操作员是受限制的生产,其中左侧必须是生产。variable

根据借用的报价

因此,PHP以唯一可能的方式解析表达式。

关于优先级的文档是正确的。.适用范围


因此,遵循(反向)生产:$a || $a = 1

variable "||" variable "=" expr
variable "||" expr_without_variable
expr "||" expr
expr

的情况是相似的,并按照(反向)生产进行解析:!$a = foo()!($a = foo())

"!" variable "=" expr
"!" expr_without_variable
"!" expr                 
expr

现在,怎么样?即使 具有比赋值更高的优先级,也不会对其进行解析。它实际上被解析为等等,由精明的读者完成。$d = $c && $e = $b && $f = $a($d = $c) && ..&&$d = ($c && ($e = ..))

虽然它可能不会被随意注意到,但这种差异能够产生不同的结果:

$a = (($c = 1) && ($d = 0));
var_dump($a, $c, $d);         // => false, 1, 0

$b = ($e = 1 && $f = 0);      // => $b = ($e = (1 && ($f = 0)));
var_dump($b, $e, $f);         // => false, false, 0

因此,当将赋值运算符与优先级较高的运算符混合在一起时,通常应使用括号,特别是当这样的结果可能是..清楚。

尽管这最初看起来不一致,但它是一个定义明确的语法 - 但技术细节隐藏在一些相当外行的文档后面;并且这些规则与其他类似C语法的语言中的规则略有不同。文档中缺少官方的EBNF无济于事。


尽管有解析细节,但从评估的角度来看,代码(有效且定义明确的语法)应该保持定义良好,因为由于保证短路,“or”的左侧必须出现在右侧之前。$a || $a = ..


相比之下,在 JavaScript 中,根据 ECMAScript 语法规则,它被解析为语法上“有效”代码。但是,不会生成有效的引用规范类型,因此会引发运行时引用错误。a || a = 1(a || a) = 1a || a


答案 2

至于您的后续问题:与:if ( $d = $c && $e = $b && $f = $a )

$d = $c;
if($d) {
    $e = $b;
    if($e) {
        $f = $a;
        if($f) {
            ...
        }
    }
}

我假设你知道这一点,但有些问题让我感到困惑,所以我会提到它... =是一个赋值运算符,而不是比较运算符。 不检查$a和$b是否相同,它使$a相等$b,然后检查$a的计算结果是否为 true。 检查两个变量是否相同。if($a = $b)if($a == $b)


推荐