有人能解释一下PHP中三元运算符简写(?:)和空合并运算符(??)之间的区别吗?
他们什么时候表现不同,什么时候表现相同(如果真的发生了的话)?
$a ?: $b
VS.
$a ?? $b
有人能解释一下PHP中三元运算符简写(?:)和空合并运算符(??)之间的区别吗?
他们什么时候表现不同,什么时候表现相同(如果真的发生了的话)?
$a ?: $b
VS.
$a ?? $b
当前回答
当你的第一个参数为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。
其他回答
It seems there are pros and cons to using either ?? or ?:. The pro to using ?: is that it evaluates false and null and "" the same. The con is that it reports an E_NOTICE if the preceding argument is null. With ?? the pro is that there is no E_NOTICE, but the con is that it does not evaluate false and null the same. In my experience, I have seen people begin using null and false interchangeably but then they eventually resort to modifying their code to be consistent with using either null or false, but not both. An alternative is to create a more elaborate ternary condition: (isset($something) or !$something) ? $something : $something_else.
下面是一个使用??同时使用null和false的运算符:
$false = null;
$var = $false ?? "true";
echo $var . "---<br>";//returns: true---
$false = false;
$var = $false ?? "true";
echo $var . "---<br>"; //returns: ---
然而,通过详细说明三元操作符,我们可以使一个假字符串或空字符串""的行为就像它是null一样,而不抛出e_notice:
$false = null;
$var = (isset($false) or !$false) ? $false : "true";
echo $var . "---<br>";//returns: ---
$false = false;
$var = (isset($false) or !$false) ? $false : "true";
echo $var . "---<br>";//returns: ---
$false = "";
$var = (isset($false) or !$false) ? $false : "true";
echo $var . "---<br>";//returns: ---
$false = true;
$var = (isset($false) or !$false) ? $false : "true";
echo $var . "---<br>";//returns: 1---
就我个人而言,我认为如果PHP的未来版本包含另一个新的操作符::?这取代了上面的语法。即: // $var = $false:?“真正的”;该语法将相等地计算null, false和“”,而不会抛出E_NOTICE…
主要的区别在于
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;在引用返回函数中 因此不工作,并发出警告。
如果你使用这样的快捷方式三元操作符,如果没有设置$_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 = 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
当你的第一个参数为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。