当前位置:  开发笔记 > 编程语言 > 正文

PHP三元运算符vs null合并运算符

如何解决《PHP三元运算符vsnull合并运算符》经验,为你挑选了7个好方法。

有人可以解释PHP中三元运算符速记(?:)和空合并运算符(??)之间的差异吗?

他们什么时候表现不同,以同样的方式(如果这种情况发生)?

$a ?: $b

VS.

$a ?? $b

MasterOdin.. 287

当你的第一个参数为null时,它们基本相同,只是E_NOTICE当你有一个未定义的变量时,null合并将不会输出.在PHP 7.0迁移的文档有这样一段话:

对于需要将三元组与isset()结合使用的常见情况,已添加空合并运算符(??)作为语法糖.它返回第一个操作数(如果存在且不为NULL); 否则返回第二个操作数.

这是一些示例代码来演示:

 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";

它的输出:

$a = false ?? 'f'; // false
$b = false ?: 'g'; // 'g'

有通知的行是我使用简写三元运算符而不是空合并运算符的行.但是,即使有通知,PHP也会给出相同的响应.

执行代码:https://3v4l.org/McavC

当然,这总是假设第一个参数是null.一旦它不再为null,那么你最终会产生差异,因为??操作符总是返回第一个参数,而?:速记只有在第一个参数是真的时才会发生,并且这依赖于PHP如何将事物类型转换为布尔值.

所以:

 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";

然后$a将等于false$b等于'g'.



1> MasterOdin..:

当你的第一个参数为null时,它们基本相同,只是E_NOTICE当你有一个未定义的变量时,null合并将不会输出.在PHP 7.0迁移的文档有这样一段话:

对于需要将三元组与isset()结合使用的常见情况,已添加空合并运算符(??)作为语法糖.它返回第一个操作数(如果存在且不为NULL); 否则返回第二个操作数.

这是一些示例代码来演示:

 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";

它的输出:

$a = false ?? 'f'; // false
$b = false ?: 'g'; // 'g'

有通知的行是我使用简写三元运算符而不是空合并运算符的行.但是,即使有通知,PHP也会给出相同的响应.

执行代码:https://3v4l.org/McavC

当然,这总是假设第一个参数是null.一旦它不再为null,那么你最终会产生差异,因为??操作符总是返回第一个参数,而?:速记只有在第一个参数是真的时才会发生,并且这依赖于PHP如何将事物类型转换为布尔值.

所以:

 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";

然后$a将等于false$b等于'g'.


这是正确的答案,但真实性检查是主要的差异,应该更加强调.
提示:如果你一直在使用?而不是?:但后来发现自己需要让你的代码与早于7的PHP版本兼容(对于ex的插件),那么你可能想换掉?? 与isset($ something)?$ something:$ something_else代码中的任何地方.使用find/replace工具,选择正则表达式选项并插入查找字段,可以使用Notepad ++或nedit(以及其他编辑器)轻松完成此操作:"\ s*(\ S +)\ s*\?\?" 并在替换字段中:"isset \($ 1 \)?$ 1:"没有引号(nedit使用\ 1而不是$ 1).然后全部替换.
@MasterOdin对您的回答不满意。两者都不一样。有不同的结果。

2> Andrew..:

如果您使用这样的快捷方式三元运算符,如果$_GET['username']未设置则会引发通知:

$val = $_GET['username'] ?: 'default';

所以你必须做这样的事情:

$val = isset($_GET['username']) ? $_GET['username'] : 'default';

空合并运算符是等同于上面的语句,将返回"默认"如果$_GET['username']没有设置或者是null:

$val = $_GET['username'] ?? 'default';

请注意,它不会检查真实性.它仅检查是否已设置且不为空.

您也可以这样做,并返回第一个定义的(set和not null)值:

$val = $input1 ?? $input2 ?? $input3 ?? 'default';

现在这是一个合适的合并运算符.



3> a20..:

在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"
所以这是我的解释:

1. Null Coalescing运算符 - ??:

??就像一个只允许NULL通过的"门".

因此,它始终返回第一个参数,除非第一个参数恰好是NULL.

这意味着??( !isset() || is_null() )

2.三元运算符 - ?:

?:就像一扇anything falsy通过的大门- 包括NULL

0,empty string,NULL,false,!isset(),empty()...任何气味falsy

就像经典的三元运算符一样: echo ($x ? $x : false)

注意:?:将抛出PHP NOTICE未定义(unset!isset())变量

3.所以,医生,做当我使用???:..

我只是在开玩笑 - 我不是医生,这只是一种解释

我会用?:

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();

4.堆叠操作员......

    三元运算符可堆叠 ...

    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 {}
    

    Null Coalese操作员可堆叠 ...

    $v = $x ?? $y ?? $z; 
    

    这是一系列:

    if(!isset($x) || is_null($x) ) {} 
    else if(!isset($y) || is_null($y) ) {}
    else {}
    

    使用堆叠,我可以缩短这个:

    if(!isset($_GET['name'])){
       if(isset($user_name) && !empty($user_name)){
          $name = $user_name;
       }else {
          $name = 'anonymous';
       }
    } else { 
       $name = $_GET['name'];
    }
    

    对此:

    $name = $_GET['name'] ?? $user_name ?: 'anonymous';
    

    很酷,对吗?:-)



4> Dhairya Lakh..:

主要区别在于

    三元运算表达式 expr1 ?: expr3返回expr1如果expr1计算结果为 TRUE,但是,从另一方面空合并运算符表达式 (expr1) ?? (expr2) 的计算结果为expr1,如果expr1 NULL

    expr1 ?: expr3如果左侧值(expr1) 不存在但是另一方面Null Coalescing Operator Null Coalescing Operator (expr1) ?? (expr2),则三元运算符会发出通知.如果左侧值不存在,则不发出通知(expr1) ,就像isset().

    TernaryOperator是左关联的

    ((true ? 'true' : false) ? 't' : 'f');
    

    Null Coalescing Operator是右关联的

    ($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 ?? $酒吧; 并返回$ var == 42?$ a:$ b; 因此,在按引用返回功能中将不起作用并发出警告.



5> Chazy Chaz..:

在动态数据处理方面,它们的行为都不同.

如果变量为空(''),则空合并将把变量视为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

链接:https://3v4l.org/ZBAa1



6> Dean Or..:

两者都是较长表达的缩写.

?:是的缩写$a ? $a : $b.如果$ a的计算结果为TRUE,则此表达式将计算为$ a .

??是的缩写isset($a) ? $a : $b.如果设置了$ a,则此表达式将计算为$ a,而不是null.

当$ a未定义或为null时,它们的用例重叠.当$ a未定义??时,不会产生E_NOTICE,但结果是相同的.当$ a为null时,结果是相同的.



7> Supun Pranee..:

对于初学者:

空合并运算符(??)

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功能

三元运算符速记(?:)

每一个虚假的东西(falsenull0,空字符串)都是来作为假的,但如果它是一个不确定的,也都为假,但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: ..

希望这可以帮助

推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有