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

有人可以解释在三元运算符速记( ?: :)和空合并运算符( ?? )之间的区别吗?

他们什么时候行为不一样,什么时候以相同的方式(如果甚至发生的话)?

 $a ?: $b 

VS.

 $a ?? $b 

它们基本上是一样的,只是当你有一个未定义的variables时,空合并不会输出一个E_NOTICE

以下是一些testing代码:

 <?php $a = null; print $a ?? 'b'; print "\n"; print $a ?: 'b'; print "\n"; print $c ?? 'a'; print "\n"; print $c ?: 'a'; print "\n"; $b = array('a' => null); print $b['a'] ?? 'd'; print "\n"; print $b['a'] ?: 'd'; print "\n"; print $b['c'] ?? 'e'; print "\n"; print $b['c'] ?: 'e'; print "\n"; 

它的输出:

 b b a Notice: Undefined variable: c in /in/apAIb on line 14 a d d e Notice: Undefined index: c in /in/apAIb on line 33 e 

有通知的行是我使用速记三元运算符而不是空合并运算符。 但是,即使有通知,PHP也会给出同样的回应。

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

当然,这总是假设第一个参数是null 。 一旦它不再是空的,那么你最终的差异在于?? 运算符将始终返回第一个参数,而?:简写只有在第一个参数是真的时才会返回,并且依赖于PHP如何将事物types转换为布尔值 。

所以:

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

那么$a等于false$b等于'g'

如果使用这样的快捷三元运算符,如果没有设置$_GET['username'] ,将会发出通知:

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

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

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

null合并运算符等同于上述语句,如果未设置$_GET['username']或返回null ,将返回'default':

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

请注意, 它不检查真实性 。 它只检查它是否设置,而不是空值。

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

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

现在,这是一个合适的合并运营商。

当涉及到dynamic数据处理时,它们的行为都不一样。

如果variables为空(''),则空合并将把该variables视为真,但速记三元运算符不会。 这是要记住的。

 $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

似乎有利弊使用???: 。 亲使用?:是它评估假和空和“”相同。 如果前面的参数是空的,它会报告一个E_NOTICE。 用?? 亲是没有E_NOTICE,但是con是它不评估false和null是相同的。 根据我的经验,我已经看到人们开始使用null和false可交替使用,但是最终他们会修改它们的代码以使其与null或false一致,但不能同时使用。 另一种方法是创build一个更复杂的三元条件: (isset($something) or !$something) ? $something : $something_else (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: --- 

然而,通过详细阐述三元操作符,我们可以使一个错误的或空的stringperformance得像一个null,而不会抛出一个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"; // $var = $false :? "true"; 该语法将等于null,false和“”,而不会抛出E_NOTICE …

向下滚动此链接并查看该部分,它给出了一个比较示例,如下所示:

 <?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'; ?> 

但是,build议不要链接操作员,因为这会使得稍后阅读代码时更难理解代码。

空合并运算符(??)已被添加为需要与isset()一起使用三元组的通常情况下的语法糖。 它返回它的第一个操作数,如果它存在并且不是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 setwhether 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将以相同的方式处理一个不存在的variables和一个设置为NULL的variables。

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 operatorNull Coalescing operator符被devise为比ternary operator更好地处理未定义的variables。 而ternary operatorif-else的简写。

Null Coalescing operator并不意味着replaceternary operator ,但是在一些使用情况下(如上例),它允许您用较less的麻烦编写干净的代码。

学分: http : //dwellupper.io/post/6/php7-null-coalescing-operator-usage-and-examples