有人能解释一下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'。
其他回答
:哦?-表示如果第一个操作数为真,则返回该操作数。否则,它将返回第二个。
?? -如果第一个操作数存在且不为空,则返回值。如果是,则返回;否则,它返回第二个操作数。
我发现一篇文章很好地描述了这种差异: https://www.fparedes.com/blog/null-coalescing-vs-elvis-operator-php/
Null Coalescing运算符只执行两个任务:它检查变量是否已设置,以及变量是否为空。看看下面的例子:
<?php
# case 1:
$greeting = 'Hola';
echo $greeting ?? 'Hi There'; # outputs: 'Hola'
# case 2:
$greeting = null;
echo $greeting ?? 'Hi There'; # outputs: 'Hi There'
# case 3:
unset($greeting);
echo $greeting ?? 'Hi There'; # outputs: 'Hi There'
上面的代码示例说明,Null Coalescing运算符以同样的方式处理一个不存在的变量和一个被设置为Null的变量。
空合并运算符是对三元运算符的改进。下面的代码片段比较了这两者:
<?php /* example: checking for the $_POST field that goes by the name of 'fullname'*/
# in ternary operator
echo "Welcome ", (isset($_POST['fullname']) && !is_null($_POST['fullname']) ? $_POST['fullname'] : 'Mr. Whosoever.'); # outputs: Welcome Mr. Whosoever.
# in null coalecing operator
echo "Welcome ", ($_POST['fullname'] ?? 'Mr. Whosoever.'); # outputs: Welcome Mr. Whosoever.
因此,两者之间的区别在于空合并操作符操作符被设计为比三元操作符更好地处理未定义变量。然而,三元操作符是if-else的简写。
Null Coalescing运算符并不意味着要取代三元运算符,但在一些用例中,比如上面的例子,它允许您以更少的麻烦编写干净的代码。
学分:http://dwellupper.io/post/6/php7-null-coalescing-operator-usage-and-examples
在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';
很酷,对吧?: -)
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.
实用的简短回答:
Try:
var_dump('' ?: 'ok');
vs
var_dump('' ?? 'ok');
如果测试值(或变量*)为false,第一个将返回“ok”
而
如果测试值(或变量*)为空或未初始化/设置,第二个将返回'ok'。
*警告:如果你想用?:测试一个变量,你必须首先确保它是初始化/设置的,否则PHP将引发一个E_NOTICE(而??不会)。