PHP中的?:运算符('Elvis运算符')

时间:2010-01-03 00:10:59

标签: php coding-style conditional-operator language-construct

我今天在一些PHP代码中看到了这一点:

$items = $items ?: $this->_handle->result('next', $this->_result, $this);

我不熟悉这里使用的?:运算符。它看起来像一个三元运算符,但是省略了判断谓词是否为真的表达式。这是什么意思?

6 个答案:

答案 0 :(得分:432)

如果左操作数为truthy,则计算左操作数,否则为右操作数。

在伪代码中,

foo = bar ?: baz;

大致解决

foo = bar ? bar : baz;

if (bar) {
    foo = bar;
} else {
    foo = baz;
}

区别在于bar只会被评估一次。

您也可以使用此功能对foo进行“自检”,如您发布的代码示例所示:

foo = foo ?: bar;

如果bar为空或假,则会将foo分配给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

Elvis operator

答案 1 :(得分:51)

请参阅the docs

  

从PHP 5.3开始,可以省略三元运算符的中间部分。如果expr1 ?: expr3评估为expr1,则表达式 expr1 会返回TRUE,否则会返回expr3

答案 2 :(得分:16)

小心数组。我们必须在?之后编写一个检查变量,因为:

  $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;

答案 3 :(得分:6)

另一个重要的考虑因素:Elvis运营商打破了Zend Opcache令牌化过程。我发现这很难!虽然这可能已在以后的版本中修复,但我可以确认PHP 5.5.38中存在此问题(使用内置的Zend Opcache v7.0.6-dev)。

如果您发现某些文件“拒绝”在Zend Opcache中缓存,这可能是其中一个原因......希望这会有所帮助!

答案 4 :(得分:3)

是的,这是PHP 5.3中的新功能。如果它被评估为TRUE,则返回测试表达式的值;如果将其评估为FALSE,则返回替代值。

答案 5 :(得分:0)

猫王运算符:

?:是猫王运算符。这是二进制运算符,它执行以下操作:

?:的左值强制为布尔值,并检查其是否为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

何时使用:

对于三元运算符的特定情况,Elvis运算符基本上是速记语法:

$testedVar ? $ testedVar : $otherVar;

Elvis运算符将通过以下方式使语法更加简洁:

$testedVar ?: $otherVar;