Alex
Alex

Reputation: 68406

Operator precedence: multiple expressions with && and ||

I encountered a code line that looks like this:

if ($users == 'all' || $_POST['user'] == 1 && $users == 'admins' || $_POST[ 'user' ] == 0 && $users == 'mods') ...

I don't understand how are all these conditions met because there are not parentheses between them :(

Is || more important than && ? Which parts get evaluated first?

Upvotes: 5

Views: 9649

Answers (3)

Ken
Ken

Reputation: 3096

It starts out going from left to right unless precedence takes over.

function rtrue($x) {
    static $rt = 0;
    echo $x . ' called true ' . ++$rt . '<br>';
    return true;
}

function rfalse($x) {
    static $rf = 0;
    echo $x . ' called false ' . ++$rf . '<br>';
    return false;
}

// all but last get called, eq: false || (true && false) || (false && true)
$result1 = rfalse('a') || rtrue('b') && rfalse('c') || rfalse('d') && rtrue('e');
echo '=== result '. ( $result1 ? 'true' : 'false' ) . '<br>';

// first true does not get called, eq: (false && true) || true
$result2 = rfalse('x') && rtrue('y') || rtrue('z');
echo '=== result '. ( $result2 ? 'true' : 'false' ) . '<br>';

Prints the following:

a called false 1
b called true 1
c called false 2
d called false 3
=== result false
x called false 4
z called true 2
=== result true

Upvotes: 1

Ben
Ben

Reputation: 16533

&& depends of the evaluation of the right expression when left one is true, || doesn't. You could rewrite it to:

if(
    $users == 'all' ||
    ($_POST['user'] == 1 && $users == 'admins') ||
    ($_POST['user'] == 0 && $users == 'mods')
)

And it'll be the same.

Upvotes: 14

WWW
WWW

Reputation: 9860

With no parenthesis, PHP will evaluate each expression from left to right, using PHP's operator precedence along the way. However, as in any logical check, throwing AND into the mix can make things confusing and a lot harder to read.

Upvotes: 1

Related Questions