Does PHP have short-circuit evaluation?

2019-01-02 15:47发布

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 checks later conditions like the up_to_length($string)? If so, then why does it do extra work when it doesn't have to?

8条回答
与君花间醉酒
2楼-- · 2019-01-02 16:21

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.

查看更多
姐姐魅力值爆表
3楼-- · 2019-01-02 16:23

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

查看更多
琉璃瓶的回忆
4楼-- · 2019-01-02 16:23

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.

查看更多
十年一品温如言
5楼-- · 2019-01-02 16:25

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 do_something() gets run only if $confirmed is true.

查看更多
刘海飞了
6楼-- · 2019-01-02 16:26

No it doesn't. This is always a good place to optimize order of conditions.

查看更多
不流泪的眼
7楼-- · 2019-01-02 16:33

In summary therefore:

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

Logical operators are AND, OR, && and ||
AND and OR always evaluate both operands.

&& and || only evaluate the right hand side if they need to.

查看更多
登录 后发表回答