有人能解释一下PHP中三元运算符简写(?:)和空合并运算符(??)之间的区别吗?
他们什么时候表现不同,什么时候表现相同(如果真的发生了的话)?
$a ?: $b
VS.
$a ?? $b
有人能解释一下PHP中三元运算符简写(?:)和空合并运算符(??)之间的区别吗?
他们什么时候表现不同,什么时候表现相同(如果真的发生了的话)?
$a ?: $b
VS.
$a ?? $b
当前回答
当涉及到动态数据处理时,它们的行为都不同。
如果变量为空("),空合并将把变量视为真值,但速记三元操作符不会。这是需要记住的。
$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
其他回答
主要的区别在于
Ternary Operator expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE but on the other hand Null Coalescing Operator expression (expr1) ?? (expr2) evaluates to expr1 if expr1 is not NULL Ternary Operator expr1 ?: expr3 emit a notice if the left-hand side value (expr1) does not exist but on the other hand Null Coalescing Operator (expr1) ?? (expr2) In particular, does not emit a notice if the left-hand side value (expr1) does not exist, just like isset(). TernaryOperator is left associative ((true ? 'true' : false) ? 't' : 'f'); Null Coalescing Operator is right associative ($a ?? ($b ?? $c));
现在让我们通过例子来解释两者的区别:
三元运算符(?:)
$x='';
$value=($x)?:'default';
var_dump($value);
// The above is identical to this if/else statement
if($x){
$value=$x;
}
else{
$value='default';
}
var_dump($value);
空合并运算符(??)
$value=($x)??'default';
var_dump($value);
// The above is identical to this if/else statement
if(isset($x)){
$value=$x;
}
else{
$value='default';
}
var_dump($value);
下面的表格解释了'?? ?和?
特别注意:空合并运算符和三元运算符是一个 表达式,并且它的值不是一个变量,而是 表达式的结果。如果你想的话,知道这一点很重要 通过引用返回一个变量。语句返回$foo ??美元的酒吧;而且 返回$var == 42 ?$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,不像三元操作符。
:哦?-表示如果第一个操作数为真,则返回该操作数。否则,它将返回第二个。
?? -如果第一个操作数存在且不为空,则返回值。如果是,则返回;否则,它返回第二个操作数。
我发现一篇文章很好地描述了这种差异: https://www.fparedes.com/blog/null-coalescing-vs-elvis-operator-php/
其他的答案更深入,给出了很好的解释。对于那些寻求快速答案的人,
$a ?: 'fallback'是$a ?$a: 'fallback'
而
一美元? ?'回退'是$a = isset($a) ?$a: 'fallback'
主要的区别在于左操作符是:
一个非空的假值(0,",false,[],…) 未定义的变量
在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';
很酷,对吧?: -)