有人能解释一下PHP中三元运算符简写(?:)和空合并运算符(??)之间的区别吗?

他们什么时候表现不同,什么时候表现相同(如果真的发生了的话)?

$a ?: $b

VS.

$a ?? $b

当前回答

如果你使用这样的快捷方式三元操作符,如果没有设置$_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';

这是一个合适的聚结算子。

其他回答

其他的答案更深入,给出了很好的解释。对于那些寻求快速答案的人,

$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(而??不会)。

当涉及到动态数据处理时,它们的行为都不同。

如果变量为空("),空合并将把变量视为真值,但速记三元操作符不会。这是需要记住的。

$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

如果你使用这样的快捷方式三元操作符,如果没有设置$_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';

这是一个合适的聚结算子。

当使用像$_GET或$_REQUEST这样的超全局变量时,你应该意识到它们可能是一个空字符串。 在这个特殊的例子中

$username = $_GET['user'] ?? 'nobody';

将失败,因为$username的值现在是一个空字符串。

所以当使用$_GET甚至$_REQUEST时,你应该像这样使用三元操作符:

$username = (!empty($_GET['user'])?$_GET['user']:'nobody';

现在$username的值是'nobody'。