有人能解释一下PHP中三元运算符简写(?:)和空合并运算符(??)之间的区别吗?
他们什么时候表现不同,什么时候表现相同(如果真的发生了的话)?
$a ?: $b
VS.
$a ?? $b
有人能解释一下PHP中三元运算符简写(?:)和空合并运算符(??)之间的区别吗?
他们什么时候表现不同,什么时候表现相同(如果真的发生了的话)?
$a ?: $b
VS.
$a ?? $b
当前回答
向下滚动这个链接并查看该部分,它为您提供了如下所示的比较示例:
<?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,不像三元操作符。
其他回答
当涉及到动态数据处理时,它们的行为都不同。
如果变量为空("),空合并将把变量视为真值,但速记三元操作符不会。这是需要记住的。
$a = NULL;
$c = '';
print $a ?? '1b';
print "\n";
print $a ?: '2b';
print "\n";
print $c ?? '1d';
print "\n";
print $c ?: '2d';
print "\n";
print $e ?? '1f';
print "\n";
print $e ?: '2f';
输出:
1b
2b
2d
1f
Notice: Undefined variable: e in /in/ZBAa1 on line 21
2f
链接:https://3v4l.org/ZBAa1
class a
{
public $a = 'aaa';
}
$a = new a();
echo $a->a; // Writes 'aaa'
echo $a->b; // Notice: Undefined property: a::$b
echo $a->a ?? '$a->a does not exists'; // Writes 'aaa'
// Does not throw an error although $a->b does not exist.
echo $a->b ?? '$a->b does not exist.'; // Writes $a->b does not exist.
// Does not throw an error although $a->b and also $a->b->c does not exist.
echo $a->b->c ?? '$a->b->c does not exist.'; // Writes $a->b->c does not exist.
当你的第一个参数为null时,它们基本上是相同的,除了当你有一个未定义的变量时,null合并不会输出一个E_NOTICE。PHP 7.0迁移文档是这样说的:
空合并运算符(??)已被添加为语法糖 对于一般情况下需要使用三元组合的 收取()。如果操作数存在且不为NULL,则返回第一个操作数; 否则返回第二个操作数。
下面是一些示例代码来演示这一点:
<?php
$a = null;
print $a ?? 'b'; // b
print "\n";
print $a ?: 'b'; // b
print "\n";
print $c ?? 'a'; // a
print "\n";
print $c ?: 'a'; // Notice: Undefined variable: c in /in/apAIb on line 14
print "\n";
$b = array('a' => null);
print $b['a'] ?? 'd'; // d
print "\n";
print $b['a'] ?: 'd'; // d
print "\n";
print $b['c'] ?? 'e'; // e
print "\n";
print $b['c'] ?: 'e'; // Notice: Undefined index: c in /in/apAIb on line 33
print "\n";
有提示的那几行是我使用的简略三元运算符而不是空合并运算符。但是,即使有通知,PHP也会返回相同的响应。
执行代码:https://3v4l.org/McavC
当然,这总是假设第一个参数为空。一旦它不再为空,你就会得到??运算符总是返回第一个参数,而?:简写只在第一个参数为真时才返回,这取决于PHP如何将东西类型转换为布尔值。
So:
$a = false ?? 'f'; // false
$b = false ?: 'g'; // 'g'
那么$a等于false, $b等于g。
其他的答案更深入,给出了很好的解释。对于那些寻求快速答案的人,
$a ?: 'fallback'是$a ?$a: 'fallback'
而
一美元? ?'回退'是$a = isset($a) ?$a: 'fallback'
主要的区别在于左操作符是:
一个非空的假值(0,",false,[],…) 未定义的变量
实用的简短回答:
Try:
var_dump('' ?: 'ok');
vs
var_dump('' ?? 'ok');
如果测试值(或变量*)为false,第一个将返回“ok”
而
如果测试值(或变量*)为空或未初始化/设置,第二个将返回'ok'。
*警告:如果你想用?:测试一个变量,你必须首先确保它是初始化/设置的,否则PHP将引发一个E_NOTICE(而??不会)。