PHP expression a || b = c

4

2
不要忘记有文档解释所有这些。在任何编程语言中,您必须了解运算符绑定强度或优先级规则。 - tadman
6个回答

9

它的缩写为:

($id == true) || (($data['created'] = $now) == true)

考虑到短路逻辑以及表达式本身的结果被忽略:
if (!$id) {
    $data['created'] = $now;
}

参见:逻辑运算符


1
||的优先级高于=时,$a || $b = $c如何简写为($a == true) || (($b = $c) == true)?它应该声明为((($a || $b) = $c) == true),不是吗?这会导致语法错误。我已经测试过了,没有语法错误。但我找不到文档说明。 - nl-x
@nl-x 是的,|| 在某种意义上具有更高的优先级,因为 $a = 123 || 456 的意思是 $a = (123 || 456);但在像上面那样的表达式中使用时,它会被处理得不同 :) 尽管如此,类似 $id || $data['created'] = $now || 'something else' 这样的表达式就非常奇怪了。 - Ja͢ck
我找到了一些文档(请看我的回答),再加上一些测试,告诉我PHP仍然允许“=”运算符在绑定到其左侧时优先执行。 - nl-x
@nl-x 不确定您所说的“在其左侧绑定之前”的意思; 尽管如此,这种特定行为非常稳定,可以在这里看到。 - Ja͢ck

1
在我看来,它的意思是:
一个 或者 将 b 赋值为 c 的可能性。
或者在你的情况下, $id 或者$data['created'] 赋值为 $now 的可能性。

0

有很多种方法可以编写这个表达式。我喜欢使用三元运算符,它和这个意思是一样的:a?a:b=c

$a=0;
$c=1;
($a) ? $a : $b=$c;
echo $b;

或者

$data['created'] = ($id) ? $id : $now;

你的代码使用了比较运算符 ||,它在短路表达式中表示 OR。你可以像我的示例一样使用 ?:,或者只需:

switch(true) {
    case $a : $a; break;
    default : $b=$c; break;
}

这也可以用IF ELSEIF ELSE列表来表达。 短路表达式、三元运算符表达式和switch比IF语句的列表更简洁,而且在我看来更快。


0
这是一个短路表达式。一般来说,这意味着表达式将被评估到找到整个结果的点为止。 因此,如果a为真(因为真或假不会改变总体结果),a || b将不会评估b,而类似于此,如果a等于false,则a && b将不会评估b
现在看你的例子:
如果a等于true,则无需评估第二个操作数b=c,并且c将不会分配给b。
如果a等于false,则将评估第二个操作数,首先将c分配给b,然后将结果作为此表达式的结果返回。

0

是的,你说得对。

但这里有一个来自手册的重要部分需要注意:

运算符优先级和结合性只决定表达式如何分组,它们并不指定表达式的计算顺序。PHP(通常情况下)不指定表达式的计算顺序,应避免编写假定特定计算顺序的代码,因为行为可能会在 PHP 的不同版本或周围代码的影响下发生变化

示例 #2 未定义的计算顺序

$a = 1;
echo $a + $a++; // may print either 2 or 3

$i = 1;
$array[$i] = $i++; // may set either index 1 or 2

注意: 虽然=的优先级比大多数其他运算符低,但PHP仍然允许类似以下表达式:if (!$a = foo()),此时foo()的返回值会被放入$a中。

-2

|| 表示或,因此 a == true OR (b = c) == true。后者很奇怪,因为你不应该在 if 语句中使用“=”。

一个工作示例是:

$a = false;
$b = 19;

if ($a == true || $b == 19)
{
    // continue here.
}

尽管$a是假的,if语句查看第二部分并且该语句为真。因此语句可以继续执行。


为什么他不应该使用'='?如果a为false,它可能是一种赋值的方式:(例如a || a = b可能具有与if(!a){a = b;}相同的效果) - Gwenc37

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接