有人能够解释一下PHP中的三元运算符简写(?:
)和null 合并运算符(??
)之间的区别吗?
它们在什么情况下会表现出不同的行为,在什么情况下又是相同的(如果有的话)?
$a ?: $b
对比。
$a ?? $b
有人能够解释一下PHP中的三元运算符简写(?:
)和null 合并运算符(??
)之间的区别吗?
它们在什么情况下会表现出不同的行为,在什么情况下又是相同的(如果有的话)?
$a ?: $b
对比。
$a ?? $b
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.
??
或?:
都有其利弊。使用?:
的好处是它将false、null和""视为相同,但缺点是如果前面的参数为null,则会报告E_NOTICE。使用??
的好处是没有E_NOTICE,但缺点是它不将false和null视为相同。根据我的经验,我发现人们开始将null和false互换使用,但最终会修改代码以使用null或false中的一个,而不是两者兼用。另一种选择是创建更复杂的三元条件:(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: ---
$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---
:?
以替换上述语法,那将非常好。即:
// $var = $false :? "true";
这种语法将平等地评估null、false和“”而不会抛出E_NOTICE...?? null ?:
这个东西真的很棒,谢谢你聪明的先生。 - Blaine Lafreniere当使用超全局变量,如 $_GET 或 $_REQUEST 时,您应该意识到它们可能是空字符串。在这种特殊情况下,例如:
$username = $_GET['user'] ?? 'nobody';
将会失败,因为$username的值现在是一个空字符串。
所以当使用$_GET甚至$_REQUEST时,你应该使用三元运算符,像这样:
$username = (!empty($_GET['user'])?$_GET['user']:'nobody';
现在$username的值如预期一样是'nobody'。
Null Coalescing operator
只执行两个任务:检查 变量是否已设置
和 是否为空
。请看以下示例:
<?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'
<?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.
Null Coalescing operator
运算符比ternary operator
更适合处理未定义的变量。而ternary operator
是if-else
的简写。
Null Coalescing operator
并不意味着要取代ternary operator
,但在某些用例中,例如上面的示例,它允许您编写更简洁的代码,减少麻烦。isset($_POST['fullname'])
已经检查了 NULL
值 - 所以第一个例子中的 && !is_null($_POST['fullname'])
是多余的。 - Yaron U.:?
- 表示如果第一个操作数为真,则返回它。否则,返回第二个操作数。
??
- 评估第一个操作数是否存在且不为空。如果是,则返回它;否则,返回第二个操作数。
我找到了一篇文章,非常好地描述了它们之间的区别: https://www.fparedes.com/blog/null-coalescing-vs-elvis-operator-php/
php -a
)。然后设置ini_set('error_reporting', 'E_ALL')
和ini_set('display_errors', 'on')
。接着你可以尝试var_dump($var ?? 'default'))
,看看在此之前设置任何类型的值会发生什么。 - St3anexpr1 ?: expr3
如果expr1
为真,则返回expr1
,否则返回expr3
。 - Basj