给出以下代码:
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)
?
如果是这样,那么为什么它在不需要时会做额外的工作呢?
Answers:
是的,PHP解释器是“惰性”的,这意味着它将尽可能少地进行比较以评估条件。
如果要验证,请尝试以下操作:
function saySomething()
{
echo 'hi!';
return true;
}
if (false && saySomething())
{
echo 'statement evaluated to true';
}
if (isset($var['index']) && $var['index'] === "something")
。如果需要在布尔表达式中求值每个条件,则在if语句之前求值并保存它们,然后在if条件中检查结果。
是的,它确实。这是一个依靠短路评估的小技巧。有时,您可能会有一个小的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
。
&&
导致php将所有内容转换为布尔值,因此将$two
其转换为true
,然后回显为1
。您将需要对其true||(echo 'no short circuit')
进行测试(或类似的测试)。
我已经创建了自己的短路评估逻辑,不幸的是,它与javascripts快速语法没有什么不同,但是也许这是一个您可能会发现有用的解决方案:
$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;
您可以跳过在问号之后再次编写true条件变量的步骤,例如:
(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的逻辑一样||
。
我的选择:不信任PHP中的短路评估...
function saySomething()
{
print ('hi!');
return true;
}
if (1 || saySomething())
{
print('statement evaluated to true');
}
条件1的第二部分|| saySomething()是无关紧要的,因为这将始终返回true。不幸的是说something()被评估并执行。
也许我误解了短路表达式的确切逻辑,但这看起来不像“它将进行尽可能少的比较”对我来说。
此外,这不仅是性能问题,如果您在比较中进行分配,或者进行了有意义的改变,而不仅仅是比较内容,那么结果可能会不同。
无论如何...要小心。
旁注:如果要避免延迟检查并运行条件的每个部分,在这种情况下,您需要使用逻辑AND,如下所示:
if (condition1 & condition2) {
echo "both true";
}
else {
echo "one or both false";
}
这在您需要例如调用两个函数(即使第一个函数返回false)时很有用。
&&
。