有人能解释一下PHP中三元运算符简写(?:)和空合并运算符(??)之间的区别吗?
他们什么时候表现不同,什么时候表现相同(如果真的发生了的话)?
$a ?: $b
VS.
$a ?? $b
有人能解释一下PHP中三元运算符简写(?:)和空合并运算符(??)之间的区别吗?
他们什么时候表现不同,什么时候表现相同(如果真的发生了的话)?
$a ?: $b
VS.
$a ?? $b
当前回答
当使用像$_GET或$_REQUEST这样的超全局变量时,你应该意识到它们可能是一个空字符串。 在这个特殊的例子中
$username = $_GET['user'] ?? 'nobody';
将失败,因为$username的值现在是一个空字符串。
所以当使用$_GET甚至$_REQUEST时,你应该像这样使用三元操作符:
$username = (!empty($_GET['user'])?$_GET['user']:'nobody';
现在$username的值是'nobody'。
其他回答
向下滚动这个链接并查看该部分,它为您提供了如下所示的比较示例:
<?php
/** Fetches the value of $_GET['user'] and returns 'nobody' if it does not exist. **/
$username = $_GET['user'] ?? 'nobody';
/** This is equivalent to: **/
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
/** Coalescing can be chained: this will return the first defined value out of $_GET['user'], $_POST['user'], and 'nobody'. **/
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
?>
null合并运算符(??)已被添加为语法糖,用于需要将三元值与isset()结合使用的常见情况。如果操作数存在且不为NULL,则返回第一个操作数;否则返回第二个操作数。
本质上,使用合并操作符将使其自动检查null,不像三元操作符。
如果你使用这样的快捷方式三元操作符,如果没有设置$_GET['username'],它会引起一个通知:
$val = $_GET['username'] ?: 'default';
所以你必须这样做:
$val = isset($_GET['username']) ? $_GET['username'] : 'default';
空合并操作符等价于上面的语句,如果$_GET['username']未设置或为空,将返回'default':
$val = $_GET['username'] ?? 'default';
注意,它不检查真实性。它只检查它是否已设置且不为空。
你也可以这样做,并且返回第一个定义的值(set而不是null):
$val = $input1 ?? $input2 ?? $input3 ?? 'default';
这是一个合适的聚结算子。
:哦?-表示如果第一个操作数为真,则返回该操作数。否则,它将返回第二个。
?? -如果第一个操作数存在且不为空,则返回值。如果是,则返回;否则,它返回第二个操作数。
我发现一篇文章很好地描述了这种差异: https://www.fparedes.com/blog/null-coalescing-vs-elvis-operator-php/
其他的答案更深入,给出了很好的解释。对于那些寻求快速答案的人,
$a ?: 'fallback'是$a ?$a: 'fallback'
而
一美元? ?'回退'是$a = isset($a) ?$a: 'fallback'
主要的区别在于左操作符是:
一个非空的假值(0,",false,[],…) 未定义的变量
两者都是较长的表达式的简写。
:是$a ?$a: $b。如果$a的值为TRUE,则该表达式的值为$a。
?? 是isset($a)的缩写吗?$a: $b。如果设置了$a且不为空,则该表达式将计算为$a。
当$a未定义或为空时,它们的用例重叠。当$a没有定义时??不会产生E_NOTICE,但是结果是一样的。当$a为空时,结果是相同的。