Does PHP have short-circuit evaluation?

会有一股神秘感。 提交于 2019-11-26 01:53:39

问题


Given the following code:

if (is_valid($string) && up_to_length($string) && file_exists($file)) 
{
    ......
}

If is_valid($string) returns false, does the php interpreter still check later conditions, like up_to_length($string)?
If so, then why does it do extra work when it doesn\'t have to?


回答1:


Yes, the PHP interpreter is "lazy", meaning it will do the minimum number of comparisons possible to evaluate conditions.

If you want to verify that, try this:

function saySomething()
{
    echo 'hi!';
    return true;
}

if (false && saySomething())
{
    echo 'statement evaluated to true';
}



回答2:


Yes, it does. Here's a little trick that relies on short-circuit evaluation. Sometimes you might have a small if statement that you'd prefer to write as a ternary, e.g.:

    if ($confirmed) {
        $answer = 'Yes';
    } else {
        $answer = 'No';
    }

Can be re-written as:

   $answer = $confirmed ? 'Yes' : 'No';

But then what if the yes block also required some function to be run?

    if ($confirmed) {
        do_something();

        $answer = 'Yes';
    } else {
        $answer = 'No';
    }

Well, rewriting as ternary is still possible, because of short-circuit evaluation:

    $answer = $confirmed && (do_something() || true) ? 'Yes' : 'No';

In this case the expression (do_something() || true) does nothing to alter the overall outcome of the ternary, but ensures that the ternary condition stays true, ignoring the return value of do_something().




回答3:


No, it doesn't anymore check the other conditions if the first condition isn't satisfied.




回答4:


Bitwise operators are & and |. They always evaluate both operands.

Logical operators are AND, OR, &&, and ||.

  • All four operators only evaluate the right side if they need to.
  • AND and OR have lower precedence than && and ||. See example below.

 

From the PHP manual:

// 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;

In this example, e will be true and f will be false.




回答5:


Based on my research now, PHP doesn't seem to have the same && short circuit operator as JavaScript.

I ran this test:

$one = true;

$two = 'Cabbage';

$test = $one && $two;

echo $test;

and PHP 7.0.8 returned 1, not Cabbage.




回答6:


I've create my own short-circuit evaluation logic, unfortunately it's nothing like javascripts quick syntax, but perhaps this is a solution you might find useful:

$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

I can not recall where I got the following logic from, but if you do the following;

(isset($var)) ? : $default_value;

You can skip having to write the true condition variable again, after the question mark, e.g:

(isset($super_long_var_name)) ? $super_long_var_name : $default_value;

As very important observation, when using the Ternary Operator this way, you'll notice that if a comparison is made it will just pass the value of that comparison, since there isn't just a single variable. E.g:

$num = 1;
$num2 = 2;
var_dump( ($num < $num2) ? : 'oh snap' );
// outputs bool 'true'



回答7:


My choice: do not trust Short Circuit evaluation in PHP...

function saySomething()
{
    print ('hi!');
    return true;
}

if (1 || saySomething())
{
    print('statement evaluated to true');
}

The second part in the condition 1 || saySomething() is irrelevant, because this will always return true. Unfortunately saySomething() is evaluated & executed.

Maybe I'm misunderstood the exact logic of short-circuiting expressions, but this doesn't look like "it will do the minimum number of comparisons possible" to me.

Moreover, it's not only a performance concern, if you do assignments inside comparisons or if you do something that makes a difference, other than just comparing stuff, you could end with different results.

Anyway... be careful.




回答8:


Side note: If you want to avoid the lazy check and run every part of the condition, in that case you need to use the logical AND like this:

if (condition1 & condition2) {
 echo "both true";
}
else {
 echo "one or both false";
}

This is useful when you need for example call two functions even if the first one returned false.



来源:https://stackoverflow.com/questions/5694733/does-php-have-short-circuit-evaluation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!