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 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
将以相同的方式处理一个不存在的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 operator
符Null Coalescing operator
符被devise为比ternary operator
更好地处理未定义的variables。 而ternary operator
是if-else
的简写。
Null Coalescing operator
并不意味着replaceternary operator
,但是在一些使用情况下(如上例),它允许您用较less的麻烦编写干净的代码。
学分: http : //dwellupper.io/post/6/php7-null-coalescing-operator-usage-and-examples