有人能解释一下PHP中三元运算符简写(?:)和空合并运算符(??)之间的区别吗?
他们什么时候表现不同,什么时候表现相同(如果真的发生了的话)?
$a ?: $b
VS.
$a ?? $b
有人能解释一下PHP中三元运算符简写(?:)和空合并运算符(??)之间的区别吗?
他们什么时候表现不同,什么时候表现相同(如果真的发生了的话)?
$a ?: $b
VS.
$a ?? $b
当前回答
两者都是较长的表达式的简写。
:是$a ?$a: $b。如果$a的值为TRUE,则该表达式的值为$a。
?? 是isset($a)的缩写吗?$a: $b。如果设置了$a且不为空,则该表达式将计算为$a。
当$a未定义或为空时,它们的用例重叠。当$a没有定义时??不会产生E_NOTICE,但是结果是一样的。当$a为空时,结果是相同的。
其他回答
如果你使用这样的快捷方式三元操作符,如果没有设置$_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';
这是一个合适的聚结算子。
对于初学者:
空合并运算符(??)
除了空值和未定义(变量/数组索引/对象属性)之外,所有内容都为真
ex:
$array = [];
$object = new stdClass();
var_export (false ?? 'second'); # false
var_export (true ?? 'second'); # true
var_export (null ?? 'second'); # 'second'
var_export ('' ?? 'second'); # ""
var_export ('some text' ?? 'second'); # "some text"
var_export (0 ?? 'second'); # 0
var_export ($undefinedVarible ?? 'second'); # "second"
var_export ($array['undefined_index'] ?? 'second'); # "second"
var_export ($object->undefinedAttribute ?? 'second'); # "second"
这基本上是检查变量(数组索引,对象属性..Etc)是存在的,不是空的。类似于isset函数
三元运算符简写(?:)
每个假的东西(false,null,0,空字符串)都是假的,但如果它是一个未定义的,它也会是假的,但Notice会抛出
ex
$array = [];
$object = new stdClass();
var_export (false ?: 'second'); # "second"
var_export (true ?: 'second'); # true
var_export (null ?: 'second'); # "second"
var_export ('' ?: 'second'); # "second"
var_export ('some text' ?? 'second'); # "some text"
var_export (0 ?: 'second'); # "second"
var_export ($undefinedVarible ?: 'second'); # "second" Notice: Undefined variable: ..
var_export ($array['undefined_index'] ?: 'second'); # "second" Notice: Undefined index: ..
var_export ($object->undefinedAttribute ?: 'second'); # "Notice: Undefined index: ..
希望这能有所帮助
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.
当使用像$_GET或$_REQUEST这样的超全局变量时,你应该意识到它们可能是一个空字符串。 在这个特殊的例子中
$username = $_GET['user'] ?? 'nobody';
将失败,因为$username的值现在是一个空字符串。
所以当使用$_GET甚至$_REQUEST时,你应该像这样使用三元操作符:
$username = (!empty($_GET['user'])?$_GET['user']:'nobody';
现在$username的值是'nobody'。
当涉及到动态数据处理时,它们的行为都不同。
如果变量为空("),空合并将把变量视为真值,但速记三元操作符不会。这是需要记住的。
$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