1

Take a look at this code:

if ($the_string = a_function_call('someid123') && $another_string = another_function_call('someid123'))
{
    // $the_string and $another_string are now both expected to be the values returned from their respective functions, and this block of code is expected to be run if both of them are not "falsey".
}

However...

if ($the_string = a_function_call('someid123') && $another_string = another_function_call('someid123'))
{
    // $the_string is now actually a boolean true. Not sure about $another_string.
}

Is this a weird bug? Or the intended behaviour? I've always thought that it was like the first scenario, and I've always coded by that assumption.

2 Answers2

0

&& has higher precedence than =. So your code is being parsed as if you'd written

if ($the_string = (a_function_call('someid123') && ($another_string = another_function_call('someid123'))))

This performs the following steps:

  1. Calls a_function_call()
  2. If that returns a truthy value, it calls another_function_call() and assigns the result to $another_string().
  3. Assigns the truth value of the && expression to $the_string
  4. Tests that truth value in the if statement.

This precedence allows you to write code like:

$success = function_1() && function_2();

If = had higher precedence, that would set $success just from function_1(), not the combination.

Adding parentheses would solve the problem:

if (($the_string = a_function_call('someid123')) 
    && ($another_string = another_function_call('someid123')))

PHP also has and and or operators that are like && and ||, but they have lower precedence than assignment; they exist to address this issue. You often see them used in code like this:

$variable = some_function(...) or die("some_function didn't work");

So simply replacing && with and would also solve the problem.

Barmar
  • 741,623
  • 53
  • 500
  • 612
0

The key is the operator precedence. The expression is evaluated as follow (pay attention to the parentheses):

if ($the_string = (a_function_call('someid123') && $another_string = another_function_call('someid123')))

$another_string takes the value from another_function_call() than is checked against a_function_call() return value through an AND operator.

Add the correct parentheses as follow to get the expected result:

if (($the_string = a_function_call('someid123')) && ($another_string = another_function_call('someid123')))

Please check the php operators precedence.

Yusef Maali
  • 2,201
  • 2
  • 23
  • 29