【问题标题】:Processing of php 'if x && y'php 'if x && y' 的处理
【发布时间】:2011-10-22 07:57:37
【问题描述】:

我想知道 php 如何处理 if 语句。 如果我有这样的东西:

if (isset($_GET['foo']) && $_GET['foo'] != $bar)

如果foo 未设置,它会立即退出 if(因为它是一个“和”语句,因此无论如何它都不会成功)还是会检查第二部分,而不是毫无意义?

【问题讨论】:

  • 在 SO 上搜索 php 惰性评估,您将得到长答案,简而言之,&& 运算符是短路的,这意味着如果发现第一个条件失败,它将不会评估第二个条件。检查this link

标签: php if-statement


【解决方案1】:

您所描述的内容称为“短路评估”。

大多数语言都是这样工作的,包括 PHP,所以它们会计算一个表达式,直到它们确定结果,然后停止,所以表达式的其余部分不会被计算。

正如你所说,这是最有效的方法。

但是,它可能会给没有经验的程序员带来麻烦,他们不会尝试这样的事情:

if(doFirstProcess() && doSecondProcess() {
    print "both processes succeeded";
}

在这种情况下,程序员希望调用这两个函数,但如果第一个函数返回false,那么第二个函数将不会被执行,因为程序已经知道足够多的函数来确定最终结果表达式,因此它将表达式的其余部分短路。

有一些语言不进行短路评估。 VB6 就是一个例子(过去)。我不了解 VB.Net,但由于它是从 VB6 演变而来的,我怀疑它会是相似的。但除此之外,我使用过的所有其他语言都使用了短路评估,包括 PHP。

PHP 手册中有一个关于此的部分:http://www.php.net/manual/en/language.operators.logical.php

您可以在此处阅读有关短路评估的更多信息:http://en.wikipedia.org/wiki/Short-circuit_evaluation

希望对您有所帮助。

【讨论】:

  • 顺便说一句,VB.NET 在某些时候添加了额外的运算符来提供短路功能。 AndOr 仍然不会短路,但 AndAlsoOrElse 会。
  • @Aether - 谢谢你...天哪,我很高兴我从来不用迁移到 VB.Net。
  • 感谢您对此的精彩解释。我只是在修改一个 PHP 脚本并想知道这个确切的问题。现在我知道了,你会得到一个赞成票(或任何堆栈调用它们)。
【解决方案2】:

这就是所谓的短路:

  • &&and 运算符从左到边执行
  • 如果认为左边是false,没有理由检查右边,所以省略,返回false

  • ||or 运算符也是从左到右执行的

  • 如果认为左侧是true,则没有理由检查右侧,所以省略,返回true

Manual example

// foo() will never get called as those operators are short-circuit

$a = (false && foo());
$b = (true  || foo());
$c = (false and foo());
$d = (true  or  foo());

【讨论】:

    【解决方案3】:

    如果第一次检查 if (isset($_GET['foo']) 返回 false,则甚至不会再检查第二部分。

    【讨论】:

      【解决方案4】:

      && 会短路(即,一旦一个条件失败就返回 false)。

      如果没有,那么拥有isset 将毫无意义——它的存在是为了防止在尝试将未定义的值与字符串进行比较时出错。

      【讨论】:

        【解决方案5】:

        将在第一个语句后熄灭。 你可以测试一下:

        将打印 1:

        if(1==1 && $a=1 == 1){
        
        }
        print $a;
        

        不会打印任何东西:

        if(1==2 && $a=1 == 1){
        
        }
        print $a;
        

        【讨论】:

          【解决方案6】:

          某些运算符,尤其是&&|| 是所谓的短路运算符,这意味着如果从第一个操作数(分别为falsetrue)中明确了运算结果,第二个操作数没有被评估。

          编辑:此外,操作数保证按顺序求值,其他运算符并非总是如此。

          【讨论】:

            【解决方案7】:

            如果第一部分为假,则停止 if。

            【讨论】:

              【解决方案8】:

              它会在第一个表达式计算结果为 false 后离开 if 语句,因为如果第一个表达式为 false 并且它们通过 AND 组合,则此语句永远不会为真

              你可以很容易地检查这个。如果它不像我说的那样,你会得到一个通知,$_GET['foo'] 没有定义

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2012-01-07
                • 1970-01-01
                • 2015-07-21
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多