【发布时间】:2010-12-31 21:26:34
【问题描述】:
我今天在一些 PHP 代码中看到了这一点:
$items = $items ?: $this->_handle->result('next', $this->_result, $this);
我不熟悉这里使用的?: 运算符。它看起来像一个三元运算符,但如果谓词为真,则评估的表达式已被省略。什么意思?
【问题讨论】:
标签: php conditional-operator language-construct
我今天在一些 PHP 代码中看到了这一点:
$items = $items ?: $this->_handle->result('next', $this->_result, $this);
我不熟悉这里使用的?: 运算符。它看起来像一个三元运算符,但如果谓词为真,则评估的表达式已被省略。什么意思?
【问题讨论】:
标签: php conditional-operator language-construct
见the docs:
从 PHP 5.3 开始,可以省略三元运算符的中间部分。如果
expr1的计算结果为TRUE,则表达式expr1 ?: expr3返回expr1,否则返回expr3。
【讨论】:
expr2 发生的事情是它只是消失了,没有被评估。 $this->expensiveComputation() ?: "nope" 与 $this->expensiveComputation() ? $this->expensiveComputation() : "nope" 不同 - expr1 只计算一次。
是的,这是 PHP 5.3 中的新功能。如果它被评估为 TRUE,则返回测试表达式的值,如果被评估为 FALSE,则返回替代值。
【讨论】:
如果左操作数是truthy,则计算左操作数,否则计算右操作数。
在伪代码中,
foo = bar ?: baz;
大致解析为
foo = bar ? bar : baz;
或
if (bar) {
foo = bar;
} else {
foo = baz;
}
区别在于bar 只会被评估一次。
您还可以使用它对foo 进行“自检”,如您发布的代码示例所示:
foo = foo ?: bar;
如果foo 为空或错误,这会将bar 分配给foo,否则它将保持foo 不变。
更多示例:
<?php
var_dump(5 ?: 0); // 5
var_dump(false ?: 0); // 0
var_dump(null ?: 'foo'); // 'foo'
var_dump(true ?: 123); // true
var_dump('rock' ?: 'roll'); // 'rock'
?>
顺便说一下,它叫做Elvis operator。
【讨论】:
null 或任何值。只是说'
||。那么blah || 'default'?
|| 运算符总是返回一个布尔值。
var_dump('' ?: 'foo'); 将是 foo
小心使用数组。我们必须在?之后写一个检查变量,因为:
$params = ['param1' => 'value1',
'param2' => 'value2',
'param3' => 'value3',];
$param1 = isset($params['param1'])?:null;
$param2 = !empty($params['param2'])?:null;
$param3 = $params['param3']?:null; // get E_NOTICE, if $params['param3'] eq false
var_dump($param1,$param2,$param3);
true // would like to expect `value1`
true // would like to expect `value2`
param3 // properly, but problem above
更新
来自 RFC。在 PHP 7 中,运算符 Null Coalesce Operator 将执行此操作,例如:
$param1 = $params['param1'] ?? null;
// Equivalent to: $param1 = isset($params['param1']) ? $params['param1'] : null;
【讨论】:
另一个重要的考虑因素:Elvis Operator 打破了 Zend Opcache 标记化过程。我发现这很难!虽然这可能已在以后的版本中得到修复,但我可以确认 PHP 5.5.38 中存在此问题(内置 Zend Opcache v7.0.6-dev)。
如果您发现您的某些文件“拒绝”缓存在 Zend Opcache 中,这可能是原因之一...希望这会有所帮助!
【讨论】:
?: 是 Elvis 运算符。这是一个二元运算符,它执行以下操作:
将?: 的左侧值强制为布尔值并检查它是否为true。如果true 会返回左边的表达式,如果是false 会返回右边的表达式。
var_dump(0 ?: "Expression not true"); // expression returns: Expression not true
var_dump("" ?: "Expression not true"); // expression returns: Expression not true
var_dump("hi" ?: "Expression not true"); // expression returns string hi
var_dump(null ?: "Expression not true"); // expression returns: Expression not true
var_dump(56 ?: "Expression not true"); // expression return int 56
猫王运算符基本上是三元运算符特定情况的简写语法,即:
$testedVar ? $testedVar : $otherVar;
Elvis 运算符将通过以下方式使语法更加简洁:
$testedVar ?: $otherVar;
【讨论】: