2010-01-03 80 views
123

操作员('猫王运营商)我这个今天看到在一些PHP代码::在PHP

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

我不熟悉的?:运营商正在用在这里。它看起来像一个三元运算符,但是要评估谓词是否为真的表达式已被省略。这是什么意思?

回答

237

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

在伪代码中,

foo = bar ?: baz; 

大致解析为

foo = bar ? bar : baz; 

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

区别在于bar将只计算一次。

您也可以使用该做的foo“自我检查”为您发布的代码示例演示:

foo = foo ?: bar; 

这将分配如果barfoofoo为空或falsey,否则将保持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

+7

确保括号中的变量存在,或者您将引发错误。 PHP不会假定它具有“null”或任何值。只是说' – DanMan 2015-08-13 11:10:20

+10

有趣的是,这个答案与维基文章构成递归循环,并没有完全解释为什么它被称为“猫王操作符”。 – fayerth 2016-02-24 16:21:01

+0

http://emoticon.wikia.com/wiki/Elvis_Presley – 2016-05-04 06:37:11

42

the docs

由于PHP 5.3,就可以离开了三元运算符的中间部分。表达式expr1 ?: expr3返回expr1如果expr1评估为TRUEexpr3否则。

+4

他们需要一个新的文档编写器,因为不可避免地有人会问expr2发生了什么。我只是把它弄碎了。 – 2010-01-03 00:33:38

2

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

+2

微妙的错误/误导;两个操作数都不需要是布尔值。重要的是第一个值是* truthy *,而不是“真”。 – 2015-02-11 21:32:06

+0

@MarkAmery澄清。应该很难以这种方式误解它。 – Atli 2015-02-17 09:08:57

7

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

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

这并不回答这个问题,对于任何试图了解何时使用猫王操作员的人来说也没有用。 – 2015-02-11 21:37:25

+3

@Mark Amery嗯..真的吗?没有帮助吗?你真的用PHP工作,看看数千例使用三元组访问数组的变量吗?好吧,我把文本改成“小心数组..” – voodoo417 2015-02-12 00:08:00

+0

所以null coalesce和elvis是一样的吗? – 2016-04-11 03:59:35

2

另一个重要的考虑:Elvis操作符打破了Zend Opcache标记化进程。我发现这很难!虽然这可能已在更高版本中得到修复,但我可以确认PHP 5.5.38中存在此问题(使用内置的Zend Opcache v7.0.6-dev)。

如果你发现你的某些文件'拒绝'在Zend Opcache中缓存,这可能是其中一个原因......希望这有助于!