Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does variable assignment in an expression work?

This is a practice I've seen before, but not very often: A variable is assigned to a value at the same time the value itself is evaluated (or is it the expression itself that is evaluated?). Example:

// Outputs "The value is 1"
$value = 1;
if ($var = $value) {
    echo "The value is $var";
}

Seems to be the same as:

$value = 1;
$var = $value;
if ($var) {
    echo "The value is $var";
}

Another example:

// Outputs "The value is 1"
$value = 1;
echo "The value is ".$var = $value;

I've been using this a little bit to shorten up my code, mainly the first example: for evaluating the first variable or expression while assigning it to another within the same expression. Something like this:

if ($status = User::save($data)) {
    echo "User saved.";
}
// do something else with $status

This seems so basic, but I can't actually find any documentation on this, maybe I'm not sure where to look. I've only recently figured out how this works after seeing it for years, and I really like using it, but I don't want to use it haphazardly.

It makes code shorter, maybe not quite as clear to some, but definitely less repetitive. Are there any caveats with this method? Is this perfectly safe or are there any cases where it might fail or cause unexpected behavior? This doesn't seem to be a very common practice, so I was hoping to find an explanation before I start "going nuts" with it. If it is documented, links to the correct page will be much appreciated.

like image 390
Wesley Murch Avatar asked Feb 24 '23 03:02

Wesley Murch


2 Answers

From http://uk3.php.net/manual/en/language.expressions.php:

PHP takes expressions much further, in the same way many other languages do. PHP is an expression-oriented language, in the sense that almost everything is an expression. Consider the example we've already dealt with, $a = 5. It's easy to see that there are two values involved here, the value of the integer constant 5, and the value of $a which is being updated to 5 as well. But the truth is that there's one additional value involved here, and that's the value of the assignment itself. The assignment itself evaluates to the assigned value, in this case 5. In practice, it means that $a = 5, regardless of what it does, is an expression with the value 5. Thus, writing something like $b = ($a = 5) is like writing $a = 5; $b = 5; (a semicolon marks the end of a statement). Since assignments are parsed in a right to left order, you can also write $b = $a = 5.

Many people would argue that you shouldn't use this behaviour very often. For instance, distinguishing between:

if ($a == 5) { ... }

and

if ($a = 5) { ... }

is tricky! The two common idiomatic ways of writing the above to distinguish them:

if (5 == $a) { ... }
if (($a = 5)) { ... }

The first is called a yoda condition and causes a syntax error if a equals character is left out. The latter won't behave any differently when run, but some code checkers will output warnings when the expression doesn't have the extra parentheses.

like image 152
Oliver Charlesworth Avatar answered Mar 05 '23 05:03

Oliver Charlesworth


http://php.net/manual/en/language.operators.precedence.php is what you probably need.

PHP expressions being evaluated in turn, in order from highest precedence to lower.
So, first we have assignment evaluated and then apply conditional statement on it. There is also some type juggling magic involved, to convert return value to boolean on the fly

Are there any caveats with this method?

Sure. If zero being a valid return value, your code may fail you. A common example is strpos() function:

if ($pos = strpos("a","aaa"))...
like image 20
Your Common Sense Avatar answered Mar 05 '23 06:03

Your Common Sense