79

给定以下代码:

if (is_valid($string) && up_to_length($string) && file_exists($file)) 
{
    ......
}

如果is_valid($string)返回false,php 解释器是否仍会检查以后的条件,例如up_to_length($string)
如果是这样,那为什么它不需要做额外的工作呢?

4

8 回答 8

105

是的,PHP 解释器是“惰性的”,这意味着它将进行尽可能少的比较来评估条件。

如果您想验证这一点,请尝试以下操作:

function saySomething()
{
    echo 'hi!';
    return true;
}

if (false && saySomething())
{
    echo 'statement evaluated to true';
}
于 2011-04-17T16:28:07.523 回答
11

是的,它确实。这是一个依赖短路评估的小技巧。有时您可能有一个小的 if 语句,您更愿意将其写成三元组,例如:

    if ($confirmed) {
        $answer = 'Yes';
    } else {
        $answer = 'No';
    }

可以重写为:

   $answer = $confirmed ? 'Yes' : 'No';

但是如果 yes 块也需要运行一些函数呢?

    if ($confirmed) {
        do_something();

        $answer = 'Yes';
    } else {
        $answer = 'No';
    }

好吧,由于短路评估,仍然可以重写为三元:

    $answer = $confirmed && (do_something() || true) ? 'Yes' : 'No';

在这种情况下,表达式 (do_something() || true) 不会改变三元的整体结果,而是确保三元条件保持不变true,而忽略 的返回值do_something()

于 2017-03-09T04:27:15.717 回答
8

位运算符&|。他们总是评估两个操作数。

逻辑运算符ANDOR&&||

  • 所有四个运算符仅在需要时才评估右侧。
  • ANDOR的优先级低于&&||。请参见下面的示例。

 

来自 PHP 手册:

// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;

// The constant false is assigned to $f before the "or" operation occurs
// Acts like: (($f = false) or true)
$f = false or true;

在此示例中,e将是truef将是false

于 2017-01-24T11:04:23.383 回答
6

根据我现在的研究,PHP 似乎没有与&&JavaScript 相同的短路运算符。

我运行了这个测试:

$one = true;

$two = 'Cabbage';

$test = $one && $two;

echo $test;

和 PHP 7.0.8 返回1,不是Cabbage

于 2019-07-11T08:47:16.783 回答
3

不,如果第一个条件不满足,它不再检查其他条件。

于 2011-04-17T16:28:06.530 回答
2

我创建了自己的短路评估逻辑,不幸的是它不像 javascripts 快速语法,但也许这是一个你可能会发现有用的解决方案:

$short_circuit_isset = function($var, $default_value = NULL) {
    return  (isset($var)) ? : $default_value;
};

$return_title = $short_circuit_isset( $_GET['returntitle'], 'God');

// Should return type 'String' value 'God', if get param is not set

我不记得我从哪里得到以下逻辑,但是如果您执行以下操作;

(isset($var)) ? : $default_value;

您可以跳过必须在问号之后再次编写真正的条件变量,例如:

(isset($super_long_var_name)) ? $super_long_var_name : $default_value;

作为非常重要的观察,当以这种方式使用三元运算符时,您会注意到,如果进行比较,它只会传递该比较的值,因为不只是一个变量。例如:

$num = 1;
$num2 = 2;
var_dump( ($num < $num2) ? : 'oh snap' );
// outputs bool 'true'
于 2015-11-30T17:01:21.770 回答
-5

旁注:如果您想避免惰性检查并运行条件的每个部分,在这种情况下,您需要使用逻辑与,如下所示:

if (condition1 & condition2) {
 echo "both true";
}
else {
 echo "one or both false";
}

当您需要调用两个函数时,这很有用,即使第一个函数返回 false。

于 2015-04-29T00:32:29.183 回答
-5

我的选择:不要相信 PHP 中的短路评估...

function saySomething()
{
    print ('hi!');
    return true;
}

if (1 || saySomething())
{
    print('statement evaluated to true');
}

条件1的第二部分|| saySomething()无关紧要,因为这将始终返回 true。不幸的是saySomething()被评估和执行。

也许我误解了短路表达式的确切逻辑,但这对我来说看起来不像“它将进行尽可能少的比较”

此外,这不仅仅是一个性能问题,如果你在比较中进行分配,或者如果你做了一些有所作为的事情,而不只是比较东西,你可能会得到不同的结果。

总之……小心点。

于 2012-01-14T10:21:08.087 回答