【问题标题】:Conditionally assigning PHP values有条件地分配 PHP 值
【发布时间】:2011-05-18 19:11:03
【问题描述】:

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

$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());

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

【问题讨论】:

    标签: php ternary-operator


    【解决方案1】:

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

    $x = expensive() ?: $default;
    

    documentation

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

    【讨论】:

    • 我个人避免使用仅限 PHP 5.3 的语法,而更喜欢 $x = expensive(); if (!$x) $x = $default;
    • 哇;我只是想评论“PHP需要GNU extension for ternaries
    • 啊哈 - 错过了手册中的内容。我认为这意味着 5.2.x 没有更好的方法(我必须在中期支持)?
    • 太糟糕了 PHP 没有使用 Javascript/Actionscript 解决方案:因为在条件中处理的值不会转换为布尔值,除非它与 && 结合使用,您可以这样做 var x = expensive() || default; 这使用已经熟悉的语法,并且在不止一种有点深奥的情况下会使 PHP 受益。
    • @Renesis 我同意——尤其是因为 PHP 的“真实性”测试如此松散——布尔运算符将对象转换为布尔值几乎是一个错误!
    【解决方案2】:

    您能否更新 SomeClass:bigQuery() 以返回新的 EmptySet() 而不是 false?

    那么你就有了

    $foo = SomeClass::bigQuery();
    

    【讨论】:

    • 这实际上是我的偏好——不幸的是,我正在构建一个从第 0 天就犯了这个错误的库,现在他们有太多东西挂在 API 上来修复它:/
    【解决方案3】:
    $foo = SomeClass::bigQuery();
    if (!$foo) $foo = new EmptySet();
    

    修订二,感谢@meagar

    【讨论】:

    • 这很烦人,我个人更喜欢其他答案。
    • 实现了一种减少冗长的方法。
    • 为什么不if (!$foo) $foo = new EmptySet();?稍微少一些 foo 的。
    • 当然,现在它实际上与@ontrack 的答案相同。不过,我认为作业永远不应该处于某种状态。
    【解决方案4】:

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

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

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

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

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

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

    【讨论】:

    • 其实需要写成:$foo = SomeClass::bigQuery() or $foo = new EmptySet();,相当于第三个选项。
    猜你喜欢
    • 1970-01-01
    • 2011-01-12
    • 2019-12-09
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多