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

?:PHP中的运算符(Elvis运算符),php,conditional-operator,language-construct,Php,Conditional Operator,Language Construct,我今天在一些PHP代码中看到了这一点: $items = $items ?: $this->_handle->result('next', $this->_result, $this); 我不熟悉这里使用的?:运算符。它看起来像一个三元运算符,但忽略了谓词为true时要求值的表达式。这是什么意思?请参见: 由于PHP5.3,可以省略三元运算符的中间部分。表达式expr1?:如果expr1的计算结果为TRUE,则expr3返回expr1,否则返回expr3 是的,这在PHP5.

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

$items = $items ?: $this->_handle->result('next', $this->_result, $this);
我不熟悉这里使用的
?:
运算符。它看起来像一个三元运算符,但忽略了谓词为true时要求值的表达式。这是什么意思?

请参见:

由于PHP5.3,可以省略三元运算符的中间部分。表达式
expr1?:如果
expr1
的计算结果为
TRUE
,则expr3
返回
expr1
,否则返回
expr3


是的,这在PHP5.3中是新的。如果测试表达式的计算结果为真,则返回测试表达式的值;如果测试表达式的计算结果为假,则返回可选值。

如果左操作数为,则返回左操作数;否则返回右操作数

在伪代码中

foo = bar ?: baz;
大致决定

foo = bar ? bar : baz;

不同的是,
bar
将只计算一次

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

foo = foo ?: bar;
如果
foo
为null或false,则将
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'
?>

顺便说一句,它叫


小心使用阵列。我们必须在
之后写入一个检查变量,因为:

  $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中,操作员将执行此操作,例如:

$param1 = $params['param1'] ?? null;
// Equivalent to:  $param1 = isset($params['param1']) ? $params['param1'] : null;

另一个重要的考虑事项是:Elvis操作符中断Zend Opcache标记化过程。我发现这很难!虽然在以后的版本中可能已经解决了这个问题,但我可以确认PHP5.5.38(内置Zend Opcache v7.0.6-dev)中存在这个问题

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

Elvis操作员:
?:
是Elvis操作员。这是一个二进制运算符,它执行以下操作:

?:
左侧的值强制为布尔值,并检查它是否为
真。如果
true
则返回左侧的表达式,如果为false,则返回右侧的表达式

例子:
var_dump(0?:“表达式不正确”);//表达式返回:表达式不为true
var_dump(“?:“表达式不正确”);//表达式返回:表达式不为true
变量转储(“hi”?:“表达式不正确”);//表达式返回字符串hi
var_dump(null?:“表达式不为真”);//表达式返回:表达式不为true
变量转储(56?:“表达式不正确”);//表达式返回int 56
何时使用: Elvis运算符基本上是三元运算符特定情况下的简写语法,即:

$testedVar ? $testedVar : $otherVar;
Elvis运算符将通过以下方式使语法更加一致:

$testedVar ?: $otherVar;

确保括号中的变量存在,否则将引发错误。PHP不会仅仅假设它的值为
null
或任何值。只要说‘为什么不直接使用
|
。所以
blah | | |“default”
?@Noitidart是因为,与JS中返回最左边的真实操作数不同,PHP中的
| |
运算符总是返回布尔值。对于任何想知道的人来说,空字符串都是假的,所以
var_dump('':'foo')
将是
foo
,所以null coalesce和elvis是一样的?@NabeelKhan不!这使得Elvis操作符在PHP imo中有点无用。Elvis操作符对表达式求值,如果为真,则返回它,否则返回最后一部分。由于PHP是低类型的,所以很多东西都是真的,或者是假的,而且很可能不是您想要的。例如:如果未定义某个变量,您希望将其设置为默认值,使用Elvis运算符PHP将表示未定义0,但您可能希望0。。。这就是为什么PHP7会得到Null Coalesce操作符,它会严格地针对Null测试您的变量,因此PHP会说0不是未定义的。有人可以使用@$arr[$key]而不是isset($arr[$key])syntax@FuscaSoftware:根据我的经验,这样使用错误抑制不是一个好主意。TBH,文档是正确的。expr2的问题是它刚刚消失,没有被评估<代码>$this->expensiveComputation()?:“nope”
$this->expensiveComputation()不同$此->expensiveComputation():“nope”
-expr1只计算一次。
$testedVar ?: $otherVar;