Answers:
当您的第一个参数为null时,它们基本相同,不同之处在于,E_NOTICE
当您有未定义的变量时,null合并不会输出。在PHP 7.0迁移的文档有这样一段话:
对于需要将三元数与isset()结合使用的常见情况,已将空合并运算符(??)添加为语法糖。如果存在,并且不为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
当然,这总是假设第一个参数是null
。一旦它不再为null,则最终会出现以下差异:??
运算符将始终返回第一个参数,而?:
简写方式只有在第一个参数为true时才返回,并且这取决于PHP如何将内容类型转换为布尔值。
所以:
$a = false ?? 'f'; // false
$b = false ?: 'g'; // 'g'
则将$a
等于false
和$b
等于'g'
。
$b = []; var_dump($b['a']['b']['c'] ?? 'default');
或带有物体$b = new Foo; var_dump($b->a()->b()->c() ?? 'default');
$a = [];
。请参阅:3v4l.org/iCCa0
在php交互模式下运行以下内容(php -a
在终端上)。每行的注释显示结果。
var_dump (false ?? 'value2'); # bool(false)
var_dump (true ?? 'value2'); # bool(true)
var_dump (null ?? 'value2'); # string(6) "value2"
var_dump ('' ?? 'value2'); # string(0) ""
var_dump (0 ?? 'value2'); # int(0)
var_dump (false ?: 'value2'); # string(6) "value2"
var_dump (true ?: 'value2'); # bool(true)
var_dump (null ?: 'value2'); # string(6) "value2"
var_dump ('' ?: 'value2'); # string(6) "value2"
var_dump (0 ?: 'value2'); # string(6) "value2"
??
:??
就像一个“门”,只允许NULL通过。NULL
。 ??
与( !isset() || is_null() )
?:
?:
就像一扇门, anything falsy
通行 -包括NULL
0
,empty string
,NULL
,false
,!isset()
,empty()
...任何气味falsyecho ($x ? $x : false)
?:
会抛出PHP NOTICE
未定义的(unset
或!isset()
)变量??
和?:
..?:
什么时候
empty($x)
检查!empty($x) ? $x : $y
可以缩短为$x ?: $y
if(!$x) { fn($x); } else { fn($y); }
可以缩短为 fn(($x ?: $y))
??
什么时候
!isset() || is_null()
检查$object = $object ?? new objClassName();
三元运算符可以堆叠 ...
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
这基本上是一个序列:
if( truthy ) {}
else if(truthy ) {}
else if(truthy ) {}
..
else {}
空煤算子可以堆叠 ...
$v = $x ?? $y ?? $z;
这是一个序列:
if(!isset($x) || is_null($x) ) {}
else if(!isset($y) || is_null($y) ) {}
else {}
使用堆栈,我可以缩短此时间:
if(!isset($_GET['name'])){
if($user_name){
$name = $user_name;
}else {
$name = 'anonymous';
}
} else {
$name = $_GET['name'];
}
对此:
$name = $_GET['name'] ?? $user_name ?: 'anonymous';
酷吧?:-)
如果使用像这样的快捷方式三元运算符,则如果$_GET['username']
未设置,将引起通知:
$val = $_GET['username'] ?: 'default';
因此,您必须执行以下操作:
$val = isset($_GET['username']) ? $_GET['username'] : 'default';
该空合并运算符是等同于上面的语句,将返回“默认”如果$_GET['username']
没有设置或者是null
:
$val = $_GET['username'] ?? 'default';
请注意,它不会检查真实性。它仅检查是否已设置并且不为null。
您也可以执行此操作,并且将返回第一个定义的(set和not null
)值:
$val = $input1 ?? $input2 ?? $input3 ?? 'default';
现在,这是一个合适的合并运算符。
主要区别在于
三元运算表达式 expr1 ?: expr3
返回expr1
如果expr1
计算结果为
TRUE
,但是,从另一方面空合并运算符表达式 (expr1) ?? (expr2)
的计算结果为expr1
,如果expr1
是不 NULL
三元操作员 expr1 ?: expr3
发出通知,如果左侧值(expr1)
不存在,但是,从另一方面空合并运算符 (expr1) ?? (expr2)
特别是,如果左侧值不发出通知(expr1)
不存在,就像isset()
。
三元运算符保持关联
((true ? 'true' : false) ? 't' : 'f');
空合并运算符是正确的关联
($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);
下面是解释之间的差异性和相似性表'??'
和?:
特别说明:null合并运算符和三进制运算符是一个表达式,它不计算变量,而是计算表达式的结果。了解是否要通过引用返回变量很重要。语句返回$ foo?$ bar; 并返回$ var == 42?$ a:$ b; 因此,按引用返回功能中的“无效”将不起作用,并发出警告。
在动态数据处理方面,两者的行为都不同。
如果变量为空(''),则空合并将变量视为true,但速记三元运算符则不会。这是要牢记的。
$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
It returns its first operand if it exists and is not NULL; otherwise it returns its second operand
。
对于初学者:
空合并运算符(??)
除null
值和未定义(变量/数组索引/对象属性)外,其他所有内容均为真
例如:
$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"
这基本上是检查变量(数组索引,对象属性等)是否存在null
。类似于isset
功能
三元运算符速记(?:)
每一个虚假的东西(false
,null
,0
,空字符串)都是来作为假的,但如果它是一个不确定的,也都为假,但Notice
会抛出
前
$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: ..
希望这可以帮助
向下滚动此链接并查看该部分,它为您提供了一个比较示例,如下所示:
<?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';
?>
但是,不建议将运算符链接在一起,因为这会使以后阅读代码时更难理解代码。
对于需要将三元数与isset()结合使用的常见情况,已将空合并运算符(??)添加为语法糖。如果存在,并且不为NULL,则返回其第一个操作数;否则,返回第一个操作数。否则返回第二个操作数。
本质上,与三元运算符不同,使用合并运算符将使其自动检查是否为空。
a || b || c
JS中的通用模式,除了PHP可以用于布尔值(false || 2
在JS中为2;false ?? 2
在PHP中为false)
似乎使用??
或都有优点和缺点?:
。使用的优点?:
是它对false和null以及“”的求值相同。缺点是,如果前面的参数为null,它将报告E_NOTICE。随着??
亲是没有E_NOTICE,但con是,它不评估虚假和无效一样。以我的经验,我看到人们开始交替使用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: ---
但是,通过详细说明三元运算符,我们可以使错误或空字符串“”表现为好像是空值,而不会引发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 :? "true";
该语法将相等地评估null,false和“”,而不抛出E_NOTICE ...
?? null ?:
事情太棒了,谢谢先生。聪明的家伙。
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.
Null Coalescing operator
仅执行两项任务:检查whether the variable is set
和whether it is null
。看下面的例子:
<?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 operator
对待不存在的变量和以NULL
相同方式设置为的变量。
Null Coalescing operator
是对的改进ternary operator
。看一下下面的代码片段,比较两者:
<?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
,而是在如上例所示的某些用例中,它使您可以编写麻烦的干净代码。
鸣谢:http : //dwellupper.io/post/6/php7-null-coalescing-operator-usage-and-examples
isset($_POST['fullname'])
已经检查过NULL
值-因此&& !is_null($_POST['fullname'])
第一个示例中的还是多余的
当使用$ _GET或$ _REQUEST之类的超全局变量时,应注意它们可能是一个空字符串。在这种情况下,这个例子
$username = $_GET['user'] ?? 'nobody';
将失败,因为$ username的值现在是一个空字符串。
因此,在使用$ _GET甚至$ _REQUEST时,应使用三元运算符,如下所示:
$username = (!empty($_GET['user'])?$_GET['user']:'nobody';
现在$ username的值是“ nobody”,符合预期。