今天我在一些 PHP 代码中看到了这个:
$items = $items ?: $this->_handle->result('next', $this->_result, $this);
我对这里使用的 ?:
运算符不熟悉。它看起来像是一个三目运算符,但如果谓词为真,则省略了要评估的表达式。这是什么意思?
今天我在一些 PHP 代码中看到了这个:
$items = $items ?: $this->_handle->result('next', $this->_result, $this);
我对这里使用的 ?:
运算符不熟悉。它看起来像是一个三目运算符,但如果谓词为真,则省略了要评估的表达式。这是什么意思?
如果左操作数为真值,则返回左操作数的值;否则返回右操作数的值。
在伪代码中,
foo = bar ?: baz;
foo = bar ? bar : baz;
或者
if (bar) {
foo = bar;
} else {
foo = baz;
}
与之不同的是,bar
只会被评估一次。
你还可以使用这个方法来对foo
进行“自检”,就像你发布的代码示例中所演示的那样:
foo = foo ?: bar;
foo
为空或为假值时将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'
var_dump('' ?: 'roll'); // 'roll'
var_dump('0' ?: 'roll'); // 'roll'
var_dump('42' ?: 'roll'); // '42'
?>
||
呢?像这样: blah || 'default'
? - Noitidart||
运算符始终返回一个布尔值。 - ksadowskivar_dump('' ?: 'foo');
将是 foo
。 - AlbinoDrought__construct(MyClient $client = null) { $client = $client ?: new MyClient; }
。当 null
是唯一的“falsey”选项时,最好使用 $client ??= new MyClient;
,它大致相当于 if ($client === null) { $client = new MyClient; }
。 - s3c请参阅文档:
自PHP 5.3以来,三元运算符的中间部分可以省略。表达式
expr1 ?: expr3
如果expr1
计算结果为TRUE
,则返回expr1
,否则返回expr3
。
expr2
发生了什么事情,它只是消失了,没有被评估。$this->expensiveComputation() ?: "nope"
不等同于 $this->expensiveComputation() ? $this->expensiveComputation() : "nope"
- expr1
只被评估一次。 - Piskvor left the building小心处理数组。我们必须在 ?
后面编写一个检查变量,因为:
$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运算符。这是一个二元运算符,它执行以下操作:
将?:
左侧的值强制转换为布尔值,并检查是否为true
。如果为true
,则返回左侧表达式,否则返回右侧表达式。
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;
var_dump([] ?: 'Expression not true');
将返回"Expression not true"。因此,Elvis运算符有点像检查empty()
,而null合并运算符(??
)更像是测试isset()
。 - BadHorsie另一个重要的考虑因素是:Elvis操作符会破坏Zend Opcache的标记化过程。我通过艰难的方式发现了这一点!虽然这个问题可能已经在以后的版本中得到解决,但我可以确认这个问题存在于PHP 5.5.38(内置Zend Opcache v7.0.6-dev)中。
如果您发现您的一些文件“拒绝”被缓存在Zend Opcache中,这可能是其中之一的原因...希望这可以帮助您!
是的,这在PHP 5.3中是新功能。它返回测试表达式的值,如果被评估为TRUE,则返回该值,否则返回替代值。
我认为目的是条件执行:
$a ?: func();
如果$a的值为FALSE,那么func()中的结果将不会被执行。它可以被用作一个简写。
if(!$a){
func();
}
这个赋值语句是可选的 $a = $a ?: func() 就像:
if(!$a){
$a = func();
}