?: PHP中的操作符(“Elvis操作符”)

时间:2021-06-26 22:25:37

I saw this today in some PHP code:

我今天在一些PHP代码中看到过:

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

I'm not familiar with the ?: operator being used here. It looks like a ternary operator, but the expression to evaluate to if the predicate is true has been omitted. What does it mean?

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

5 个解决方案

#1


280  

It evaluates to the left operand if the left operand is truthy, and the right operand otherwise.

如果左操作数是真实的,则计算结果为左操作数,否则计算结果为右操作数。

In pseudocode,

在伪代码,

foo = bar ?: baz;

roughly resolves to

大致解决了

foo = bar ? bar : baz;

or

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

with the difference that bar will only be evaluated once.

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

You can also use this to do a "self-check" of foo as demonstrated in the code example you posted:

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

foo = foo ?: bar;

This will assign bar to foo if foo is null or falsey, else it will leave foo unchanged.

如果foo是null或falsey,它会将bar赋给foo,否则会保持foo不变。

Some more examples:

一些例子:

<?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'
?>

By the way, it's called the Elvis operator.

顺便说一下,它叫做猫王操作员。

?: PHP中的操作符(“Elvis操作符”)

#2


42  

See the docs:

看到文档:

Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.

因为PHP 5.3,所以可以省略三元运算符的中间部分。表达式expr1 ?: expr3返回expr1(如果expr1计算为TRUE),而expr3则返回expr1。

#3


9  

Be careful with arrays. We must write a checking variable after ?, because:

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

  $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

Updated

更新

From RFC. In the future (in PHP 7) operator Null Coalesce Operator will do it, for example:

从RFC。将来(在PHP 7中)运算符Null Coalesce运算符也会这样做,例如:

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

#4


3  

Another important consideration: The Elvis Operator breaks the Zend Opcache tokenization process. I found this the hard way! While this may have been fixed in later versions, I can confirm this problem exists in PHP 5.5.38 (with in-built Zend Opcache v7.0.6-dev).

另一个重要的考虑:Elvis操作符破坏了Zend Opcache标记化过程。我发现这条路很难走!虽然这可能是在以后的版本中修复的,但是我可以确定这个问题存在于PHP 5.5.38中(内置Zend Opcache v7.0.6-dev)。

If you find that some of your files 'refuse' to be cached in Zend Opcache, this may be one of the reasons... Hope this helps!

如果您发现您的一些文件“拒绝”被缓存在Zend Opcache中,这可能是原因之一……希望这可以帮助!

#5


2  

Yes, this is new in PHP 5.3. It returns either the value of the test expression if it is evaluated as TRUE, or the alternative value if it is evaluated as FALSE.

是的,这在PHP 5.3中是新的。它要么返回测试表达式的值(如果它被求值为TRUE),要么返回替代值(如果它被求值为FALSE)。

#1


280  

It evaluates to the left operand if the left operand is truthy, and the right operand otherwise.

如果左操作数是真实的,则计算结果为左操作数,否则计算结果为右操作数。

In pseudocode,

在伪代码,

foo = bar ?: baz;

roughly resolves to

大致解决了

foo = bar ? bar : baz;

or

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

with the difference that bar will only be evaluated once.

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

You can also use this to do a "self-check" of foo as demonstrated in the code example you posted:

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

foo = foo ?: bar;

This will assign bar to foo if foo is null or falsey, else it will leave foo unchanged.

如果foo是null或falsey,它会将bar赋给foo,否则会保持foo不变。

Some more examples:

一些例子:

<?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'
?>

By the way, it's called the Elvis operator.

顺便说一下,它叫做猫王操作员。

?: PHP中的操作符(“Elvis操作符”)

#2


42  

See the docs:

看到文档:

Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.

因为PHP 5.3,所以可以省略三元运算符的中间部分。表达式expr1 ?: expr3返回expr1(如果expr1计算为TRUE),而expr3则返回expr1。

#3


9  

Be careful with arrays. We must write a checking variable after ?, because:

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

  $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

Updated

更新

From RFC. In the future (in PHP 7) operator Null Coalesce Operator will do it, for example:

从RFC。将来(在PHP 7中)运算符Null Coalesce运算符也会这样做,例如:

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

#4


3  

Another important consideration: The Elvis Operator breaks the Zend Opcache tokenization process. I found this the hard way! While this may have been fixed in later versions, I can confirm this problem exists in PHP 5.5.38 (with in-built Zend Opcache v7.0.6-dev).

另一个重要的考虑:Elvis操作符破坏了Zend Opcache标记化过程。我发现这条路很难走!虽然这可能是在以后的版本中修复的,但是我可以确定这个问题存在于PHP 5.5.38中(内置Zend Opcache v7.0.6-dev)。

If you find that some of your files 'refuse' to be cached in Zend Opcache, this may be one of the reasons... Hope this helps!

如果您发现您的一些文件“拒绝”被缓存在Zend Opcache中,这可能是原因之一……希望这可以帮助!

#5


2  

Yes, this is new in PHP 5.3. It returns either the value of the test expression if it is evaluated as TRUE, or the alternative value if it is evaluated as FALSE.

是的,这在PHP 5.3中是新的。它要么返回测试表达式的值(如果它被求值为TRUE),要么返回替代值(如果它被求值为FALSE)。