PHP 猫王运算符与空合并运算符
PHP Elvis operator vs null coalescing operator
谁能解释一下 ternary operator shorthand (?:
) and null coalescing operator (??
) 和 PHP 之间的区别?
他们什么时候行为不同,什么时候行为相同(如果发生这种情况)?
$a ?: $b
VS.
$a ?? $b
向下滚动 this link 并查看该部分,它为您提供了一个比较示例,如下所示:
<?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';
?>
The null coalescing operator (??) has been added as syntactic sugar for the common case of needing to use a ternary in conjunction with isset(). It returns its first operand if it exists and is not NULL; otherwise it returns its second operand.
本质上,与三元运算符不同,使用合并运算符将使它自动检查 null。
当您的第一个参数为 null 时,它们基本相同,只是当您有未定义的变量时 null 合并不会输出 E_NOTICE
。 PHP 7.0 migration docs 是这样说的:
The null coalescing operator (??) has been added as syntactic sugar
for the common case of needing to use a ternary in conjunction with
isset(). It returns its first operand if it exists and is not NULL;
otherwise it returns its second operand.
下面是一些示例代码来演示这一点:
<?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";
有通知的行是我使用 shorthand 三元运算符而不是空合并运算符的行。但是,即使有通知,PHP 也会给出相同的回复。
当然,这总是假设第一个参数是null
。一旦它不再为 null,那么您最终会发现差异,因为 ??
运算符总是 return 第一个参数,而 ?:
shorthand 仅当第一个参数是真实的,这取决于 PHP would type-cast things to a boolean.
所以:
$a = false ?? 'f'; // false
$b = false ?: 'g'; // 'g'
然后 $a
等于 false
并且 $b
等于 'g'
.
在动态数据处理方面,两者的行为不同。
如果变量为空 ( '' ),null 合并会将变量视为 true,但 shorthand 三元运算符不会。这是要记住的事情。
$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
Link: https://3v4l.org/ZBAa1
像这样使用快捷三元运算符,如果没有设置$_GET['username']
会引起提示:
$val = $_GET['username'] ?: 'default';
所以你必须这样做:
$val = isset($_GET['username']) ? $_GET['username'] : 'default';
null coalescing operator等价于上面的语句,如果$_GET['username']
没有设置或者是return'default' =16=]:
$val = $_GET['username'] ?? 'default';
请注意它不检查真实性。它只检查它是否已设置而不是 null。
您也可以这样做,第一个 defined(设置而不是 null
)值将是 returned:
$val = $input1 ?? $input2 ?? $input3 ?? 'default';
现在这是一个合适的合并运算符。
似乎使用 ??
或 ?:
各有利弊。使用 ?:
的优点是它评估 false 和 null 与 "" 相同。缺点是如果前面的参数为空,它会报告 E_NOTICE。使用 ??
的优点是没有 E_NOTICE,但缺点是它不会对 false 和 null 求值相同。根据我的经验,我看到人们开始交替使用 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: ---
不过,通过详细说明三元运算符,我们可以使假字符串或空字符串 "" 的行为就好像它是 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 的未来修订版包含另一个新运算符::?
来取代上述语法,那就太好了。 IE:
// $var = $false :? "true";
该语法将对 null、false 和 "" 进行同等评估,并且不会抛出 E_NOTICE...
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
的 shorthand。
Null Coalescing operator
并不是要取代 ternary operator
,但在某些用例中,例如上面的示例,它可以让您轻松编写干净的代码。
致谢:http://dwellupper.io/post/6/php7-null-coalescing-operator-usage-and-examples
主要区别在于
三元运算符 表达式 expr1 ?: expr3
returns expr1
if expr1
的计算结果为
TRUE
但另一方面 空合并运算符 表达式 (expr1) ?? (expr2)
如果 expr1
是 不是 NULL
,计算结果为 expr1
三元
运算符 expr1 ?: expr3
如果左侧
值 (expr1)
不存在,但另一方面 Null Coalescing Operator (expr1) ?? (expr2)
特别是,如果左侧值 [=23] 不发出通知=] 确实
不存在,就像 isset()
。
TernaryOperator 是左结合的
((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);
这里是解释'??'
和?:
之间异同的table
Special Note : null coalescing operator and ternary operator is an
expression, and that it doesn't evaluate to a variable, but to the
result of an expression. This is important to know if you want to
return a variable by reference. The statement return $foo ?? $bar; and
return $var == 42 ? $a : $b; in a return-by-reference function will
therefore not work and a warning is issued.
运行 以下 php 交互模式(php -a
在终端)。每行的注释显示结果。
var_export (false ?? 'value2'); // false
var_export (true ?? 'value2'); // true
var_export (null ?? 'value2'); // value2
var_export ('' ?? 'value2'); // ""
var_export (0 ?? 'value2'); // 0
var_export (false ?: 'value2'); // value2
var_export (true ?: 'value2'); // true
var_export (null ?: 'value2'); // value2
var_export ('' ?: 'value2'); // value2
var_export (0 ?: 'value2'); // value2
空合并运算符??
??
就像一道“门”,只让NULL通过.
- 所以,它总是returns第一个参数,除非第一个参数恰好是
NULL
.
- 这意味着
??
与 ( !isset() || is_null() )
相同
使用??
- 缩短
!isset() || is_null()
检查
- 例如
$object = $object ?? new objClassName();
堆叠 Null Coalese 运算符
$v = $x ?? $y ?? $z;
// This is a sequence of "SET && NOT NULL"s:
if( $x && !is_null($x) ){
return $x;
} else if( $y && !is_null($y) ){
return $y;
} else {
return $z;
}
三元运算符?:
?:
就像一扇门,让 anything falsy
通过 - 包括 NULL
- 任何虚假的东西:
0
、empty string
、NULL
、false
、!isset()
、empty()
- 与旧的三元运算符相同:
X ? Y : Z
- 注意:
?:
将在未定义(unset
或 !isset()
)变量上抛出 PHP NOTICE
使用?:
- 正在检查
empty()
、!isset()
、is_null()
等
- 将
!empty($x) ? $x : $y
等三元运算缩短为$x ?: $y
- 将
if(!$x) { echo $x; } else { echo $y; }
缩短为echo $x ?: $y
堆叠三元运算符
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
// Source & Credit: http://php.net/manual/en/language.operators.comparison.php#95997
// This is basically a sequence of:
if( truthy ) {}
else if(truthy ) {}
else if(truthy ) {}
..
else {}
两者叠加,我们可以缩短:
if( isset($_GET['name']) && !is_null($_GET['name'])) {
$name = $_GET['name'];
} else if( !empty($user_name) ) {
$name = $user_name;
} else {
$name = 'anonymous';
}
为此:
$name = $_GET['name'] ?? $user_name ?: 'anonymous';
酷吧? :-)
两者都是较长表达式的简写形式。
?:
是 $a ? $a : $b
的缩写。如果 $a 的计算结果为 TRUE.
,则此表达式的计算结果为 $a
??
是 isset($a) ? $a : $b
的缩写。如果设置了 $a 且不为空,则此表达式的计算结果为 $a。
当 $a 未定义或为空时,它们的用例重叠。当 $a 未定义时,??
不会产生 E_NOTICE,但结果是相同的。当 $a 为 null 时,结果相同。
当使用像 $_GET 或 $_REQUEST 这样的超全局变量时,您应该知道它们可能是一个空字符串。
在这种特殊情况下,这个例子
$username = $_GET['user'] ?? 'nobody';
将失败,因为 $username 现在的值为空字符串。
因此,当使用 $_GET 甚至 $_REQUEST 时,您应该像这样使用三元运算符:
$username = (!empty($_GET['user'])?$_GET['user']:'nobody';
现在 $username 的值是预期的 'nobody'。
初学者:
空合并运算符 (??)
除了 null
值和未定义的(variable/array index/object 属性)
之外,一切都是真的
例如:
$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
函数
三元运算符shorthand(?:)
所有错误的东西(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: ..
希望对您有所帮助
其他答案很深入,解释也很好。对于那些寻求快速答案的人,
$a ?: 'fallback'
是 $a ? $a : 'fallback'
而
$a ?? 'fallback'
是 $a = isset($a) ? $a : 'fallback'
主要区别在于左侧运算符是:
- 一个不为空的虚假值(
0
、''
、false
、[]
、...)
- 一个未定义的变量
实用简答:
尝试:
var_dump('' ?: 'ok');
对
var_dump('' ?? 'ok');
如果测试值(或变量*)计算为,第一个将return 'ok'
false
而
如果测试值(或变量*)是,第二个将return'ok'
null
是否initialized/set.
*注意:如果你想用 ?:
测试一个 变量 ,你必须首先确保它是 initialized/set,否则 PHP将引发 E_NOTICE
(而 ??
不会)。
谁能解释一下 ternary operator shorthand (?:
) and null coalescing operator (??
) 和 PHP 之间的区别?
他们什么时候行为不同,什么时候行为相同(如果发生这种情况)?
$a ?: $b
VS.
$a ?? $b
向下滚动 this link 并查看该部分,它为您提供了一个比较示例,如下所示:
<?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';
?>
The null coalescing operator (??) has been added as syntactic sugar for the common case of needing to use a ternary in conjunction with isset(). It returns its first operand if it exists and is not NULL; otherwise it returns its second operand.
本质上,与三元运算符不同,使用合并运算符将使它自动检查 null。
当您的第一个参数为 null 时,它们基本相同,只是当您有未定义的变量时 null 合并不会输出 E_NOTICE
。 PHP 7.0 migration docs 是这样说的:
The null coalescing operator (??) has been added as syntactic sugar for the common case of needing to use a ternary in conjunction with isset(). It returns its first operand if it exists and is not NULL; otherwise it returns its second operand.
下面是一些示例代码来演示这一点:
<?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";
有通知的行是我使用 shorthand 三元运算符而不是空合并运算符的行。但是,即使有通知,PHP 也会给出相同的回复。
当然,这总是假设第一个参数是null
。一旦它不再为 null,那么您最终会发现差异,因为 ??
运算符总是 return 第一个参数,而 ?:
shorthand 仅当第一个参数是真实的,这取决于 PHP would type-cast things to a boolean.
所以:
$a = false ?? 'f'; // false
$b = false ?: 'g'; // 'g'
然后 $a
等于 false
并且 $b
等于 'g'
.
在动态数据处理方面,两者的行为不同。
如果变量为空 ( '' ),null 合并会将变量视为 true,但 shorthand 三元运算符不会。这是要记住的事情。
$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
Link: https://3v4l.org/ZBAa1
像这样使用快捷三元运算符,如果没有设置$_GET['username']
会引起提示:
$val = $_GET['username'] ?: 'default';
所以你必须这样做:
$val = isset($_GET['username']) ? $_GET['username'] : 'default';
null coalescing operator等价于上面的语句,如果$_GET['username']
没有设置或者是return'default' =16=]:
$val = $_GET['username'] ?? 'default';
请注意它不检查真实性。它只检查它是否已设置而不是 null。
您也可以这样做,第一个 defined(设置而不是 null
)值将是 returned:
$val = $input1 ?? $input2 ?? $input3 ?? 'default';
现在这是一个合适的合并运算符。
似乎使用 ??
或 ?:
各有利弊。使用 ?:
的优点是它评估 false 和 null 与 "" 相同。缺点是如果前面的参数为空,它会报告 E_NOTICE。使用 ??
的优点是没有 E_NOTICE,但缺点是它不会对 false 和 null 求值相同。根据我的经验,我看到人们开始交替使用 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: ---
不过,通过详细说明三元运算符,我们可以使假字符串或空字符串 "" 的行为就好像它是 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 的未来修订版包含另一个新运算符::?
来取代上述语法,那就太好了。 IE:
// $var = $false :? "true";
该语法将对 null、false 和 "" 进行同等评估,并且不会抛出 E_NOTICE...
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
的 shorthand。
Null Coalescing operator
并不是要取代 ternary operator
,但在某些用例中,例如上面的示例,它可以让您轻松编写干净的代码。
致谢:http://dwellupper.io/post/6/php7-null-coalescing-operator-usage-and-examples
主要区别在于
三元运算符 表达式
expr1 ?: expr3
returnsexpr1
ifexpr1
的计算结果为TRUE
但另一方面 空合并运算符 表达式(expr1) ?? (expr2)
如果expr1
是 不是NULL
,计算结果为 三元 运算符
expr1 ?: expr3
如果左侧 值(expr1)
不存在,但另一方面 Null Coalescing Operator(expr1) ?? (expr2)
特别是,如果左侧值 [=23] 不发出通知=] 确实 不存在,就像isset()
。TernaryOperator 是左结合的
((true ? 'true' : false) ? 't' : 'f');
空合并运算符 是右结合运算符
($a ?? ($b ?? $c));
expr1
现在让我们举例说明两者的区别:
三元运算符 (?:)
$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);
这里是解释'??'
和?:
之间异同的table
Special Note : null coalescing operator and ternary operator is an expression, and that it doesn't evaluate to a variable, but to the result of an expression. This is important to know if you want to return a variable by reference. The statement return $foo ?? $bar; and return $var == 42 ? $a : $b; in a return-by-reference function will therefore not work and a warning is issued.
运行 以下 php 交互模式(php -a
在终端)。每行的注释显示结果。
var_export (false ?? 'value2'); // false
var_export (true ?? 'value2'); // true
var_export (null ?? 'value2'); // value2
var_export ('' ?? 'value2'); // ""
var_export (0 ?? 'value2'); // 0
var_export (false ?: 'value2'); // value2
var_export (true ?: 'value2'); // true
var_export (null ?: 'value2'); // value2
var_export ('' ?: 'value2'); // value2
var_export (0 ?: 'value2'); // value2
空合并运算符??
??
就像一道“门”,只让NULL通过.- 所以,它总是returns第一个参数,除非第一个参数恰好是
NULL
. - 这意味着
??
与( !isset() || is_null() )
相同
使用??
- 缩短
!isset() || is_null()
检查 - 例如
$object = $object ?? new objClassName();
堆叠 Null Coalese 运算符
$v = $x ?? $y ?? $z;
// This is a sequence of "SET && NOT NULL"s:
if( $x && !is_null($x) ){
return $x;
} else if( $y && !is_null($y) ){
return $y;
} else {
return $z;
}
三元运算符?:
?:
就像一扇门,让anything falsy
通过 - 包括NULL
- 任何虚假的东西:
0
、empty string
、NULL
、false
、!isset()
、empty()
- 与旧的三元运算符相同:
X ? Y : Z
- 注意:
?:
将在未定义(unset
或!isset()
)变量上抛出PHP NOTICE
使用?:
- 正在检查
empty()
、!isset()
、is_null()
等 - 将
!empty($x) ? $x : $y
等三元运算缩短为$x ?: $y
- 将
if(!$x) { echo $x; } else { echo $y; }
缩短为echo $x ?: $y
堆叠三元运算符
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
// Source & Credit: http://php.net/manual/en/language.operators.comparison.php#95997
// This is basically a sequence of:
if( truthy ) {}
else if(truthy ) {}
else if(truthy ) {}
..
else {}
两者叠加,我们可以缩短:
if( isset($_GET['name']) && !is_null($_GET['name'])) {
$name = $_GET['name'];
} else if( !empty($user_name) ) {
$name = $user_name;
} else {
$name = 'anonymous';
}
为此:
$name = $_GET['name'] ?? $user_name ?: 'anonymous';
酷吧? :-)
两者都是较长表达式的简写形式。
?:
是 $a ? $a : $b
的缩写。如果 $a 的计算结果为 TRUE.
??
是 isset($a) ? $a : $b
的缩写。如果设置了 $a 且不为空,则此表达式的计算结果为 $a。
当 $a 未定义或为空时,它们的用例重叠。当 $a 未定义时,??
不会产生 E_NOTICE,但结果是相同的。当 $a 为 null 时,结果相同。
当使用像 $_GET 或 $_REQUEST 这样的超全局变量时,您应该知道它们可能是一个空字符串。 在这种特殊情况下,这个例子
$username = $_GET['user'] ?? 'nobody';
将失败,因为 $username 现在的值为空字符串。
因此,当使用 $_GET 甚至 $_REQUEST 时,您应该像这样使用三元运算符:
$username = (!empty($_GET['user'])?$_GET['user']:'nobody';
现在 $username 的值是预期的 'nobody'。
初学者:
空合并运算符 (??)
除了 null
值和未定义的(variable/array index/object 属性)
例如:
$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
函数
三元运算符shorthand(?:)
所有错误的东西(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: ..
希望对您有所帮助
其他答案很深入,解释也很好。对于那些寻求快速答案的人,
$a ?: 'fallback'
是 $a ? $a : 'fallback'
而
$a ?? 'fallback'
是 $a = isset($a) ? $a : 'fallback'
主要区别在于左侧运算符是:
- 一个不为空的虚假值(
0
、''
、false
、[]
、...) - 一个未定义的变量
实用简答:
尝试:
var_dump('' ?: 'ok');
对
var_dump('' ?? 'ok');
如果测试值(或变量*)计算为,第一个将return 'ok'
false
而
如果测试值(或变量*)是,第二个将return'ok'
null
是否initialized/set.
*注意:如果你想用 ?:
测试一个 变量 ,你必须首先确保它是 initialized/set,否则 PHP将引发 E_NOTICE
(而 ??
不会)。