有人能解释一下PHP中三元运算符简写(?:)和空合并运算符(??)之间的区别吗?
他们什么时候表现不同,什么时候表现相同(如果真的发生了的话)?
$a ?: $b
VS.
$a ?? $b
有人能解释一下PHP中三元运算符简写(?:)和空合并运算符(??)之间的区别吗?
他们什么时候表现不同,什么时候表现相同(如果真的发生了的话)?
$a ?: $b
VS.
$a ?? $b
当前回答
两者都是较长的表达式的简写。
:是$a ?$a: $b。如果$a的值为TRUE,则该表达式的值为$a。
?? 是isset($a)的缩写吗?$a: $b。如果设置了$a且不为空,则该表达式将计算为$a。
当$a未定义或为空时,它们的用例重叠。当$a没有定义时??不会产生E_NOTICE,但是结果是一样的。当$a为空时,结果是相同的。
其他回答
在php交互模式(php -a on terminal)上运行下面的代码。每行上的注释显示结果。
var_export (false ?? 'value2'); // false
var_export (true ?? 'value2'); // true
var_export (null ?? 'value2'); // value2
var_export ('' ?? 'value2'); // ""
var_export (0 ?? 'value2'); // 0
var_export (false ?: 'value2'); // value2
var_export (true ?: 'value2'); // true
var_export (null ?: 'value2'); // value2
var_export ('' ?: 'value2'); // value2
var_export (0 ?: 'value2'); // value2
空合并运算符??
?? 就像一个“门”,只让NULL通过。 它总是返回第一个参数,除非第一个参数恰好是NULL。 这意味着??与(!isset() || is_null())相同
使用??
Shorten !isset() || is_null()检查 例如$object = $object ??新objClassName ();
堆叠空合并运算符
$v = $x ?? $y ?? $z;
// This is a sequence of "SET && NOT NULL"s:
if( $x && !is_null($x) ){
return $x;
} else if( $y && !is_null($y) ){
return $y;
} else {
return $z;
}
三元运算符?:
?:就像一个门,让任何虚假的东西通过-包括NULL 任何错误:0,空字符串,NULL, false, !isset(),空() 就像以前的三元运算符:X ?Y: z 注意:?:将在未定义(unset或!isset())变量上抛出PHP NOTICE
?的用法:
检查empty(), !isset(), is_null()等 缩短三元操作像!empty($x) ?$x: $y到$x ?: $y 缩短if(!$x) {echo $x;} else {echo $y;回显$x ?: $y
叠加三元运算符
echo 0 ?: 1 ?: 2 ?: 3; //1
echo 1 ?: 0 ?: 3 ?: 2; //1
echo 2 ?: 1 ?: 0 ?: 3; //2
echo 3 ?: 2 ?: 1 ?: 0; //3
echo 0 ?: 1 ?: 2 ?: 3; //1
echo 0 ?: 0 ?: 2 ?: 3; //2
echo 0 ?: 0 ?: 0 ?: 3; //3
// Source & Credit: http://php.net/manual/en/language.operators.comparison.php#95997
// This is basically a sequence of:
if( truthy ) {}
else if(truthy ) {}
else if(truthy ) {}
..
else {}
将两者叠加,我们可以将其缩短为:
if( isset($_GET['name']) && !is_null($_GET['name'])) {
$name = $_GET['name'];
} else if( !empty($user_name) ) {
$name = $user_name;
} else {
$name = 'anonymous';
}
:
$name = $_GET['name'] ?? $user_name ?: 'anonymous';
很酷,对吧?: -)
实用的简短回答:
Try:
var_dump('' ?: 'ok');
vs
var_dump('' ?? 'ok');
如果测试值(或变量*)为false,第一个将返回“ok”
而
如果测试值(或变量*)为空或未初始化/设置,第二个将返回'ok'。
*警告:如果你想用?:测试一个变量,你必须首先确保它是初始化/设置的,否则PHP将引发一个E_NOTICE(而??不会)。
如果你使用这样的快捷方式三元操作符,如果没有设置$_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 ?$a: $b。如果$a的值为TRUE,则该表达式的值为$a。
?? 是isset($a)的缩写吗?$a: $b。如果设置了$a且不为空,则该表达式将计算为$a。
当$a未定义或为空时,它们的用例重叠。当$a没有定义时??不会产生E_NOTICE,但是结果是一样的。当$a为空时,结果是相同的。
当涉及到动态数据处理时,它们的行为都不同。
如果变量为空("),空合并将把变量视为真值,但速记三元操作符不会。这是需要记住的。
$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