Recently i came upon such snippet:
$x = 2 && $y = 3; echo (int)$x.':'.(int)$y;
Which produces output 1:3
.
By looking at operator precedence sheet i see that logical operators ||
and &&
has higher precedence than assignment operator =
. So first expression should be evaluated as $x = (2 && $y) = 3;
which becomes $x = (2 && null) = 3;
and finally evaluates to $x = false = 3;
Secondly - assignment operator has right associativity, so interpreter should try to execute false = 3
which is illegal of course. So in my opinion above mentioned code snippet should not compile at all and must throw parse or run-time error. But instead of that script produces 1:3. Which means that interpreter executed actions are:
a) $y=3
b) 2 && $y
c) $x = (2 && $y)
Why it is so and not according to operator precedence ?
The operator precedence sheet you link to states as a separate note:
Although = has a lower precedence than most other operators, PHP will still allow expressions similar to the following: if (!$a = foo()), in which case the return value of foo() is put into $a.
So, in effect, an assignment inside an expression will be treated somewhat like a sub-expression. Exactly how and when this will happen isn't clear from the documentation, which just states that "similar" expressions will work this way.