本文翻译自:PHP ternary operator vs null coalescing operator
Can someone explain the differences between ternary operator shorthand ( ?:
) and null coalescing operator ( ??
) in PHP? 有人可以解释PHP中的三元运算符速记( ?:
:)和空合并运算符( ??
)之间的区别吗?
When do they behave differently and when in the same way (if that even happens)? 它们什么时候表现不同,什么时候以相同的方式表现(如果甚至发生)?
$a ?: $b
VS. VS。
$a ?? $b
#1楼
参考:https://stackoom.com/question/2l3A6/PHP三元运算符vs空合并运算符
#2楼
Scroll down on this link and view the section, it gives you a comparative example as seen below: 向下滚动此链接并查看该部分,它为您提供了一个比较示例,如下所示:
<?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';
?>
However, it is not advised to chain the operators as it makes it harder to understand the code when reading it later on. 但是,不建议将运算符链接在一起,因为这会使以后阅读代码时更难理解代码。
The null coalescing operator (??) has been added as syntactic sugar for the common case of needing to use a ternary in conjunction with isset(). 对于需要将三元数与isset()结合使用的常见情况,已将空合并运算符(??)添加为语法糖。 It returns its first operand if it exists and is not NULL; 如果它存在且不为NULL,则返回其第一个操作数;否则返回第一个操作数。 otherwise it returns its second operand. 否则返回第二个操作数。
Essentially, using the coalescing operator will make it auto check for null unlike the ternary operator. 本质上,与三元运算符不同,使用合并运算符将使其自动检查是否为空。
#3楼
When your first argument is null, they're basically the same except that the null coalescing won't output an E_NOTICE
when you have an undefined variable. 当您的第一个参数为null时,它们基本相同,只是当您有未定义的变量时,空合并不会输出E_NOTICE
。 The PHP 7.0 migration docs has this to say: PHP 7.0迁移文档的内容如下:
The null coalescing operator (??) has been added as syntactic sugar for the common case of needing to use a ternary in conjunction with isset(). 对于需要将三元数与isset()结合使用的常见情况,已将空合并运算符(??)添加为语法糖。 It returns its first operand if it exists and is not NULL; 如果它存在且不为NULL,则返回其第一个操作数;否则返回第一个操作数。 otherwise it returns its second operand. 否则返回第二个操作数。
Here's some example code to demonstrate this: 这是一些示例代码来演示这一点:
<?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";
The lines that have the notice are the ones where I'm using the shorthand ternary operator as opposed to the null coalescing operator. 注意的行是我使用速记三元运算符而不是空合并运算符的行。 However, even with the notice, PHP will give the same response back. 但是,即使有此通知,PHP也会给出相同的响应。
Execute the code: https://3v4l.org/McavC 执行代码: https : //3v4l.org/McavC
Of course, this is always assuming the first argument is null
. 当然,这总是假设第一个参数为null
。 Once it's no longer null, then you end up with differences in that the ??
一旦它不再为null,则最终会导致区别??
operator would always return the first argument while the ?:
shorthand would only if the first argument was truthy, and that relies on how PHP would type-cast things to a boolean . 仅当第一个参数为true时,运算符始终会返回?:
简写形式的第一个参数,这取决于PHP如何将内容类型转换为boolean 。
So: 所以:
$a = false ?? 'f'; // false
$b = false ?: 'g'; // 'g'
would then have $a
be equal to false
and $b
equal to 'g'
. 则$a
等于false
而$b
等于'g'
。
#4楼
Both of them behave differently when it comes to dynamic data handling. 在动态数据处理方面,两者的行为都不同。
If the variable is empty ( '' ) the null coalescing will treat the variable as true but the shorthand ternary operator won't. 如果变量为空(''),则空合并将变量视为true,但速记三元运算符则不会。 And that's something to have in mind. 这是要牢记的。
$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';
And the output: 并输出:
1b
2b
2d
1f
Notice: Undefined variable: e in /in/ZBAa1 on line 21
2f
Link: https://3v4l.org/ZBAa1 链接: https : //3v4l.org/ZBAa1
#5楼
If you use the shortcut ternary operator like this, it will cause a notice if $_GET['username']
is not set: 如果您这样使用快捷方式三元运算符,那么如果未设置$_GET['username']
,则会引起通知:
$val = $_GET['username'] ?: 'default';
So instead you have to do something like this: 因此,您必须执行以下操作:
$val = isset($_GET['username']) ? $_GET['username'] : 'default';
The null coalescing operator is equivalent to the above statement, and will return 'default' if $_GET['username']
is not set or is null
: 空合并运算符等效于上述语句,并且如果未设置$_GET['username']
或为null
,则将返回'default':
$val = $_GET['username'] ?? 'default';
Note that it does not check truthiness . 请注意, 它不会检查真实性 。 It checks only if it is set and not null. 它仅检查是否已设置并且不为null。
You can also do this, and the first defined (set and not null
) value will be returned: 您也可以执行此操作,并且将返回第一个定义的 (set而不是null
)值:
$val = $input1 ?? $input2 ?? $input3 ?? 'default';
Now that is a proper coalescing operator. 现在,这是一个合适的合并运算符。
#6楼
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. 使用?:
的优点是它对false和null以及“”的求值相同。 The con is that it reports an E_NOTICE if the preceding argument is null. 缺点是,如果前面的参数为null,它将报告E_NOTICE。 With ??
与??
the pro is that there is no E_NOTICE, but the con is that it does not evaluate false and null the same. 优点是没有E_NOTICE,但是缺点是它不求假,并且null不变。 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. 以我的经验,我看到人们开始交替使用null和false,但后来他们最终诉诸修改代码以与使用null或false一致,但不能同时使用两者。 An alternative is to create a more elaborate ternary condition: (isset($something) or !$something) ? $something : $something_else
另一种方法是创建一个更复杂的三元条件: (isset($something) or !$something) ? $something : $something_else
(isset($something) or !$something) ? $something : $something_else
. (isset($something) or !$something) ? $something : $something_else
。
The following is an example of the difference of using the ??
以下是使用??
的区别的示例 operator using both null and false: 运算符同时使用null和false:
$false = null;
$var = $false ?? "true";
echo $var . "---<br>";//returns: true---
$false = false;
$var = $false ?? "true";
echo $var . "---<br>"; //returns: ---
By elaborating on the ternary operator however, we can make a false or empty string "" behave as if it were a null without throwing an e_notice: 但是,通过详细说明三元运算符,我们可以使错误或空字符串“”表现为好像是空值,而不会引发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---
Personally, I think it would be really nice if a future rev of PHP included another new operator: :?
我个人认为,如果以后的PHP版本中包含另一个新的运算符,那将非常好:?
that replaced the above syntax. 替换了上面的语法。 ie: // $var = $false :? "true";
即: // $var = $false :? "true";
// $var = $false :? "true";
That syntax would evaluate null, false, and "" equally and not throw an E_NOTICE... 该语法将相等地评估null,false和“”,并且不会抛出E_NOTICE ...