我如何让PHP避免懒惰评估?

时间:2009-04-02 18:09:50

标签: php function lazy-evaluation boolean-logic

我对PHP评估布尔表达式的方式有一个有趣的问题。例如,当你有

$expression = $expression1 and $expression2;

if ($expression1 and $expression2)

PHP首先检查$expression1是否评估为 true 。如果不是这种情况,则只需跳过$expression2以避免不必要的计算。在我写的剧本中,我有:

if ($validator->valid("title") and $validator->valid("text"))

我需要评估第二个语句($validator->valid("text")),即使第一个语句的计算结果为false。我想问一下,是否有一些简单的方法可以强制PHP始终评估这两个语句。谢谢!

6 个答案:

答案 0 :(得分:26)

$isValidTitle = $validator->valid("title");
$isValidText = $validator->valid("text");
if($isValidTitle && $isValidText)
{
    ...
}

那会适合吗?

答案 1 :(得分:11)

这称为short circuit evaluation,要避免它,您需要使用单个&执行此操作:

if($validator->valid("title") & $validator->valid("text")) {

}

请注意,这不是logical operators,而是实际bitwise operators

  

它们是作用于数字的二进制表示的运算符。它们不将逻辑值(即“true”或“false”)作为参数,而不先将它们分别转换为数字1和0。它们也不会返回逻辑值,而是返回数字。当然,您可以稍后将这些数字视为逻辑值(在这种情况下,0将转换为“false”,其他任何内容都转换为“true”),但这是PHP类型转换规则的结果,并且无关与运营商的行为。

因此,关于使用这种副作用来规避短路评估是否是好的做法存在一些争论。我个人至少会评论说&是故意的,但是如果你想尽可能地纯洁,你应该首先评估它们是否有效,然后再做if。

答案 2 :(得分:4)

尝试分别评估每个术语:

$term1 = $validator->valid("title");
$term2 = $validator->valid("text");
if($term1 && $term2) {
//things to do
}

答案 3 :(得分:3)

这可能不是最佳实现,但您可以随时执行:

$a=$validator->valid("title");
$b=$validator->valid("text");
if($a && $b) {...}

答案 4 :(得分:1)

您可以定义如下函数:

function logical_and($x,$y) {return ($x && $y);}

由于PHP使用call-by-value,因此可以正常工作。

答案 5 :(得分:0)

或者,如果您可以修改类$ validator实例化,则可以使有效方法接受字符串或数组。如果它是一个数组,它将运行每个项目上已存在的代码,并且只有在所有项目都“有效”时才返回TRUE。