PHP’s && has higher precedence than =

Translation: the operands of a logical && operator (not to be confused with the similar but infrequently used and operator) get evaluated before the operands of an assignment = operator (see operator precedence for more).

In PHP people frequently use the evaluation step of an if or while control structure to assign a value and then perform some action on that value, provided it evaluates to true, e.g.

if ($return_value = some_function()) {
  // do something with $return_value
}

However, should you be tempted to both test whether the returned value is true and whether another flag is set (as I was today), make sure to not do this (as I did):

if ($return_value = some_function() && $flag == 'some value') {
  // do something with $return_value
}

…because some_function() && $flag == 'some value' will get evaluated first and then the boolean result of that will get assigned to $return_value, instead of the intended return value of some_function().

This problem is easily solved with parentheses:

if (($return_value = some_function()) && $flag == 'some value') {
  // do something with $return_value
}

Lesson learned.

comments: 4 so far...

name
blog (optional)
comment

As an alternative, you could always use the ‘and’ operator. It has a lower precedence than == so it does not fail in this manner, and it makes the code easier to read as a bonus.

Your code:

if ($return_value = some_function()) {
  // do something with $return_value
}

is incorrect; in PHP one must use a double enter character, or else it always equates to true.

If (1=2) {
 // this will always execute
}

whereas

If (1==2) {
 // this will never execute
}

Jared, actually my code is just fine. Please reread my post.

Very often in PHP people take advantage of the ability to combine assignment and logical evaluation in a single if-clause. This is frequently used in database iteration code, such as in the examples for mysql_fetch_array(). e.g.

while ($row = mysql_fetch_array($result, MYSQL_NUM)) {
    printf("ID: %s  Name: %s", $row[0], $row[1]);
}

IMHO, the best solution in general is to use parens. Ok you’re not as cool as the college student who can take 5 minutes to explain why their statement works, but 2 years down the line, you can look at your statement and know what it does at a glance and so can anyone who looks at your code. Cool post though as always. Took me a while to stumble onto this one…

monthchunks

license

Justinsomnia is licensed under a Creative Commons Attribution 3.0 License.

Please see my Attribution Policy for more information.