: PHP中的操作符('Elvis操作符'

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

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

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

198617 次浏览

看到的文档:

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

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

如果左操作数为真相,则返回左操作数,否则返回右操作数。

在伪代码,

foo = bar ?: baz;

粗略地解决

foo = bar ? bar : baz;

if (bar) {
foo = bar;
} else {
foo = 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'
?>

顺便说一下,它被称为< em >猫王操作符< / em >

猫王操作员

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

  $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标记化过程。这是我很不容易才发现的!虽然在后来的版本中可能已经修复了这个问题,但我可以确认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

使用时间:

Elvis操作符基本上是三元操作符特定情况的速记语法,即:

$testedVar ? $testedVar : $otherVar;

Elvis操作符将以以下方式使语法更加简洁:

$testedVar ?: $otherVar;

我认为目的是有条件执行:

$a ?: func();

只有当$a的值解析为FALSE时,func()中的results才会执行。它可以用作…的缩写

if(!$a){
func();
}

赋值是可选的$a = $a ?: func()就像:

if(!$a){
$a = func();
}