23

对于基于表达式的结果为变量赋值的非常常见的情况,我是三元运算符的粉丝:

$foo = $bar ? $a : b;

但是,如果 $bar 是一个相对昂贵的操作,并且如果结果是真实的,我想将 $bar 的结果分配给 $foo,那么这是低效的:

$foo = SomeClass::bigQuery() ? SomeClass::bigQuery() : new EmptySet();

一种选择是:

$foo = ($result = SomeClass::bigQuery()) ? $result : new EmptySet();

但我宁愿没有额外$result的记忆。

我最好的选择是:

$foo = ($foo = SomeClass::bigQuery()) ? $foo : new EmptySet();

或者,没有三元运算符:

if(!$foo = SomeClass::bigQuery()) $foo = new EmptySet();

或者,如果程序流运算符不是您的风格:

($foo = SomeClass::bigQuery()) || ($foo = new EmptySet());

这么多选择,没有一个真的令人满意。您会使用哪个,我是否在这里遗漏了一些非常明显的东西?

4

4 回答 4

40

PHP 5.3 引入了一种新语法来解决这个问题:

$x = expensive() ?: $default;

请参阅文档

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

于 2010-12-01T22:18:41.203 回答
8

你能更新 SomeClass:bigQuery() 以返回一个新的 EmptySet() 而不是 false 吗?

然后你只有

$foo = SomeClass::bigQuery();
于 2010-12-01T22:19:05.863 回答
1
$foo = SomeClass::bigQuery();
if (!$foo) $foo = new EmptySet();

修订二,信用@meagar

于 2010-12-01T22:20:07.907 回答
1

您最后一个选项的轻微变化:

$foo = SomeClass::bigQuery() 或 new EmptySet(); 这实际上不起作用,感谢您的注意。

经常与 mySQL 代码结合使用,但在类似情况下似乎总是被遗忘:

$result = mysql_query($sql) or die(mysql_error());

虽然我个人更喜欢你已经提到的一个:

if(!$foo = SomeClass::bigQuery())
    $foo = new EmptySet();
于 2010-12-01T23:38:08.680 回答