给出以下代码:
if (is_valid($string) && up_to_length($string) && file_exists($file))
{
......
}
如果
is_valid($string)
返回 false
,php 解释器是否仍然检查后面的条件,例如 up_to_length($string)
?是的,PHP 解释器是“惰性的”,这意味着它将执行尽可能少的比较来评估条件。
如果您想验证这一点,请尝试以下操作:
function saySomething()
{
echo 'hi!';
return true;
}
if (false && saySomething())
{
echo 'statement evaluated to true';
}
是的,确实如此。这是一个依赖于短路评估的小技巧。有时您可能有一个小的 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()
的返回值。
位运算符是
&
和|
。
他们总是评估两个操作数。
AND
、OR
、&&
和||
。
AND
和 OR
的优先级低于 &&
和 ||
。请参阅下面的示例。
来自 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
将是 true
,f
将是 false
。
根据我现在的研究,PHP 似乎没有与 JavaScript 相同的
&&
短路运算符。
我进行了这个测试:
$one = true;
$two = 'Cabbage';
$test = $one && $two;
echo $test;
并且 PHP 7.0.8 返回
1
,而不是 Cabbage
。
不,如果第一个条件不满足,它不再检查其他条件。
我创建了自己的短路求值逻辑,不幸的是它与 javascript 的快速语法完全不同,但也许这是一个您可能会觉得有用的解决方案:
$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'
在此示例中,我预计根据 https://www.php.net/manual/en/language.operators.precedence.php 的优先规则,$a 等于 $b。然而,由于短路,$a 为 true,$b 为 false。
<?php
$a = 1 || 0 && 0;
$b = (1 || 0) && 0;
PHP 短路
||
和 &&
。
这里有一个小测试:
function retfalse() { echo "FALSE\n"; return false; }
function rettrue() { echo "TRUE\n"; return true; }
$a = retfalse() || rettrue();
$b = rettrue() || retfalse();
应打印:
FALSE
TRUE
TRUE
我的选择:不相信PHP中的短路评估...
function saySomething()
{
print ('hi!');
return true;
}
if (1 || saySomething())
{
print('statement evaluated to true');
}
条件第二部分1 || saySomething() 是无关紧要的,因为它总是返回 true。不幸的是 saySomething() 被评估并执行。
也许我误解了短路表达式的确切逻辑,但这看起来不像“它将进行尽可能少的比较”对我来说。
此外,这不仅仅是一个性能问题,如果你在比较中进行分配,或者如果你做了一些有影响的事情,而不仅仅是比较东西,你可能会得到不同的结果。
无论如何...要小心。
旁注: 如果您想避免延迟检查并运行条件的每个部分,在这种情况下,您需要使用逻辑 AND,如下所示:
if (condition1 & condition2) {
echo "both true";
}
else {
echo "one or both false";
}
当您需要调用两个函数(即使第一个函数返回 false)时,这非常有用。