PHP || 和 && 逻辑优化

6

我有点追求优化(至少按照我的定义如此),这个问题已经困扰了我很长时间。

我想知道 PHP 是否对 && 和 || 进行了一些优化: 接下来看一个例子:

$a = "apple";
$b = "orange";
if ($a == "orange" && $b == "orange") {
    //do stuff
}

当该代码执行时,它会检查$a是否等于“orange”。在这种情况下它不是。然而,有一个&&运算符。由于第一部分($a ==“orange”)已经返回false,PHP是否仍然会检查$b是否等于“orange”?
我对||也有同样的问题:
$a = "orange";
$b = "orange";
if ($a == "orange" || $b == "orange") {
    //do stuff
}

当它检查$a是否等于"orange"时,它会返回true。由于这将使||运算符返回true,PHP甚至会检查||的第二部分吗(因为我们已经知道它将是true)? 希望我表达清楚了,希望有人能回答我的问题。谢谢!

这是我一直以来的假设。在实践中,AND运算符确实是这样工作的。例如,我可以这样做 if (isset($a) && $a instanceof SomeClass && $a->someMethod() == 'orange') 它必须通过每个条件步骤来测试下一个。但是,除了我知道它可以工作之外,我没有任何依据。 - Logan Bibby
2
为什么不试试呢?if (true || die()) { echo '1';}if (true && die()) { echo '1';} - Mike B
2个回答

7
PHP使用二进制条件语句(例如&&||或它们的常量等效物)进行短路评估,因此如果评估左侧表达式的结果意味着右侧表达式不必要,那么右侧表达式将不会被执行。
例如...
method_exists($obj, 'func') AND $obj->func();

这是对这个事实的利用。在这个例子中,只有当LHS返回一个“真值”时,才会评估RHS。这里的逻辑是有道理的,因为你只想调用一个存在的方法(只要你不使用__call(),但那是另一回事)。你也可以以类似的方式使用OR。
defined('BASE_PATH') OR die('Restricted access to this file.');

这个模式经常被用作PHP文件中的第一行,这些文件旨在被包含而不是直接访问。如果BASE_PATH常量不存在,则LHS为falsy,因此执行RHS,该RHS会die()脚本。


你能用通俗易懂的话再说一遍吗?哈哈。我会在谷歌上快速搜索这些词语。 - Jacob Brunson
@DrAgonmoray 在第一个条件之后,PHP 只会在必要时评估其他条件 :) - rawb
@DrAgonmoray 我已经添加了一个示例,希望它比阅读我的解释更清晰 :) - alex

1

是的,PHP会短路&&||运算符,这意味着如果左操作数的值意味着不需要评估右操作数,那么右操作数将不会被评估。因此,没有必要对它们进行优化。您可以像这样测试它:

function one() {
    echo "One";
    return false;
}

function two() {
    echo "Two";
    return true;
}

one() && two(); // Outputs One
echo "\n";
two() || one(); // Outputs Two

这里有一个演示。 如果没有短路,你会得到:

OneTwo
TwoOne

如果重要的事情应该在函数two()中发生,那么可能永远不会发生,所以在编写代码时要小心限制行数 ;) - Herbert Van-Vliet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接