我如何让PHP避免懒惰评估?
-
22-08-2019 - |
题
我对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始终评估这两个陈述。谢谢!
解决方案
这被称为 短路评估, 为了避免它,您需要使用一个 &
:
if($validator->valid("title") & $validator->valid("text")) {
}
是对数字二进制表示的运营商。他们不会将逻辑值(即“ true”或“ false”)作为参数,而无需首先将其转换为数字1和0。它们也不返回逻辑值,而是数字。当然,您稍后可以将这些数字视为逻辑值(在这种情况下为0被施加到“ false”,其他任何东西都被铸造为“ true”),但这是PHP类型铸造规则的结果,而无事可做与操作员的行为。
因此,有 一些 关于使用这种副作用来规避短路评估是很好的做法。我个人至少会发表评论,说&是有意的,但是如果您想尽可能纯净,则应评估它们是否有效,然后进行IF。
其他提示
$isValidTitle = $validator->valid("title");
$isValidText = $validator->valid("text");
if($isValidTitle && $isValidText)
{
...
}
那适合吗?
尝试分别评估每个术语:
$term1 = $validator->valid("title");
$term2 = $validator->valid("text");
if($term1 && $term2) {
//things to do
}
This might not be the best implementation, but you could always do:
$a=$validator->valid("title");
$b=$validator->valid("text");
if($a && $b) {...}
You can define a function like:
function logical_and($x,$y) {return ($x && $y);}
Since PHP uses call-by-value, this works.
Alternatively, if you can modify the class $validator instantiates, you could make the valid method accept a string or an array. If it's an array, it runs the code that already exists on each item and only returns TRUE if all items are "valid".