我在Symfony框架(版本4)代码中发现了这样一段代码:
$env = $_SERVER['APP_ENV'] ?? 'dev';
我不确定这实际上是什么,但我想象它扩展成这样:
$env = $_SERVER['APP_ENV'] != null ? $_SERVER['APP_ENV'] : 'dev';
或者:
$env = isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : 'dev';
有谁对这个问题有精确的解释吗?
$myVar = $someVar ?? 42;
等价于:
$myVar = isset($someVar) ? $someVar : 42;
对于常量,当使用一个已经存在的常量时,行为是相同的:
define("FOO", "bar");
define("BAR", null);
$MyVar = FOO ?? "42";
$MyVar2 = BAR ?? "42";
echo $MyVar . PHP_EOL; // bar
echo $MyVar2 . PHP_EOL; // 42
然而,对于不存在的常数,情况就不同了:
$MyVar3 = IDONTEXIST ?? "42"; // Raises a warning
echo $MyVar3 . PHP_EOL; // IDONTEXIST
警告:使用未定义的常量IDONTEXIST -假设'IDONTEXIST'(这将在未来的PHP版本中抛出错误)
Php会将不存在的常量转换为字符串。
你可以使用constant("ConstantName")来返回常量的值,如果常量不存在,则返回null,但它仍然会引发警告。你可以在函数前加上错误控制操作符@来忽略警告消息:
$myVar = @constant("IDONTEXIST") ?? "42"; // No warning displayed anymore
echo $myVar . PHP_EOL; // 42
它是在php 7.0中添加的“空合并运算符”。它如何工作的定义是:
如果操作数存在且不为NULL,则返回第一个操作数;否则返回第二个操作数。
它实际上就是一个方便的操作符中的isset()
这两个是等价的:
$foo = $bar ?? 'something';
$foo = isset($bar) ? $bar : 'something';
文档:http://php.net/manual/en/language.operators.comparison.php language.operators.comparison.coalesce
在PHP7的新特性列表中:http://php.net/manual/en/migration70.new-features.php#migration70.new-features.null-coalesce-op
和原始RFC https://wiki.php.net/rfc/isset_ternary
编辑:因为这个答案得到了很多人的观看,所以需要澄清一下:
这是有区别的:In case of ?,第一个表达式只计算一次,而不是?:,表达式首先在条件部分求值,然后在“answer”部分求值。
$myVar = $someVar ?? 42;
等价于:
$myVar = isset($someVar) ? $someVar : 42;
对于常量,当使用一个已经存在的常量时,行为是相同的:
define("FOO", "bar");
define("BAR", null);
$MyVar = FOO ?? "42";
$MyVar2 = BAR ?? "42";
echo $MyVar . PHP_EOL; // bar
echo $MyVar2 . PHP_EOL; // 42
然而,对于不存在的常数,情况就不同了:
$MyVar3 = IDONTEXIST ?? "42"; // Raises a warning
echo $MyVar3 . PHP_EOL; // IDONTEXIST
警告:使用未定义的常量IDONTEXIST -假设'IDONTEXIST'(这将在未来的PHP版本中抛出错误)
Php会将不存在的常量转换为字符串。
你可以使用constant("ConstantName")来返回常量的值,如果常量不存在,则返回null,但它仍然会引发警告。你可以在函数前加上错误控制操作符@来忽略警告消息:
$myVar = @constant("IDONTEXIST") ?? "42"; // No warning displayed anymore
echo $myVar . PHP_EOL; // 42