考虑以下代码:
if (is_valid($string) && up_to_length($string) && file_exists($file))
{
......
}
如果 is_valid($string)
返回 false
,PHP 解释器是否仍会检查后续条件,如 up_to_length($string)
?如果是这样,那么为什么它要做额外的工作呢?
考虑以下代码:
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 (isset($var['index']) && $var['index'] === "something")
。如果你需要评估布尔表达式中的每个条件,则在 if 语句之前评估它们并保存结果,然后在 if 条件中检查结果。 - Justin C位运算符为&
和|
。它们总是对两个操作数进行评估。
逻辑运算符有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
。&&
和||
优先级低,除此之外,在语义上与&&
和||
相同。 - axiac是的,它可以。这里有一个小技巧,依赖于短路求值。有时候你可能会有一个小的if语句,你更希望将其写成三元运算符,例如:
if ($confirmed) {
$answer = 'Yes';
} else {
$answer = 'No';
}
可以重写为:
$answer = $confirmed ? 'Yes' : 'No';
但是如果“是”分支也需要运行某些功能怎么办?
if ($confirmed) {
do_something();
$answer = 'Yes';
} else {
$answer = 'No';
}
好的,将其改写成三目运算符仍然是可能的,因为存在短路求值:
$answer = $confirmed && (do_something() || true) ? 'Yes' : 'No';
true
,忽略了do_something()
的返回值。根据我的研究,PHP似乎没有像JavaScript一样的&&
短路运算符。
我运行了以下测试:
$one = true;
$two = 'Cabbage';
$test = $one && $two;
echo $test;
PHP 7.0.8返回了1
,而不是Cabbage
。
&&
会使PHP将所有内容强制转换为布尔值,这样 $two
就会被转换为 true
,随后输出为 1
。要测试这个条件,你需要使用 true||(echo 'no short circuit')
或类似的语句。 - Teepeemm我已经创建了自己的短路评估逻辑,不幸的是它与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'
?:
的逻辑与 JavaScript/Perl 的 ||
一样工作。 - trysis我的选择:在 PHP 中不要相信短路评估...
function saySomething()
{
print ('hi!');
return true;
}
if (1 || saySomething())
{
print('statement evaluated to true');
}
条件语句中的第二部分1 || saySomething()是无关紧要的,因为它总是返回true。不幸的是,saySomething()被评估和执行了。
也许我误解了短路表达式的确切逻辑,但这对我来说看起来并不像"它将尽可能少地进行比较"。
此外,这不仅是性能问题,如果您在比较中进行赋值或者做一些与仅仅比较不同的事情,您可能会得到不同的结果。
无论如何...要小心。
function saySomething()
{
print ('嗨!');
return true;
}
if (1 || saySomething())
{
print('再见');
}
- chillywilly小提示:如果你想避免懒惰检查并运行条件的每个部分,那么你需要像这样使用逻辑与:
if (condition1 & condition2) {
echo "both true";
}
else {
echo "one or both false";
}
当你需要调用两个函数时,即使第一个函数返回false,这将是很有用的。
&&
。 - deceze1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
- Patricio Rossi$a == 1
并且 $b == 2
,那么 $a
和 $b
都不是 FALSE
,但是 $a & $b == FALSE
。 - axiac
+
是完全急切的,二进制和/或也是如此。不,我确定我在询问逻辑与和逻辑或不短路的语言。 - user395760