30

The negation operator has higher precedence than the assignment operator, why is it lower in an expression?

e.g.

if (!$var = getVar()) {

In the previous expression the assignment happens first, the negation later. Shouldn't the negation be first, then the assignment?

goyote
  • 573
  • 5
  • 13

3 Answers3

47

The left hand side of = has to be a variable. $var is a variable, whereas !$var is not (it's an expr_without_variable).

Thus PHP parses the expression in the only possible way, namely as !($var = getVar()). Precedence never comes to play here.

An example of where the the precedence of = is relevant is this:

$a = $b || $c // ==> $a = ($b || $c), because || has higher precedence than =
$a = $b or $c // ==> ($a = $b) or $c, because or has lower precedence than =
NikiC
  • 100,734
  • 37
  • 191
  • 225
  • 6
    While the accepted answer is technically correct, this answer is more thorough and easier to understand. – Logos Mar 01 '13 at 03:17
  • 2
    Yes, if it were possible I'd delete my answer in favour of this one. – VolkerK Mar 01 '13 at 07:14
  • You can flag it for moderator attention and explain if you want. That said, I don't think your answer is bad (or be deleted). This one is just better. :) – Amal Murali Nov 16 '13 at 19:01
  • @NikiC Could you update the link to `zend_language_parser.y`? Because it's the trunk the content of line 738 changes. Bunch about `traits` there now. Thanks – Rudie Sep 20 '15 at 10:03
  • @NikiC Perfect. I still don't get it =) but thanks nonetheless. – Rudie Sep 20 '15 at 17:14
4

In short, assignments will always have precedence over their left part (as it would result in a parse error in the contrary case).

 <?php
 $b=12 + $a = 5 + 6;
 echo "$a $b\n";
 --> 11 23

 $b=(12 + $a) = (5 + 6);
 echo "$a $b\n";
 --> Parse error

The PHP documentation has now a note concerning this question: http://php.net/manual/en/language.operators.precedence.php (i guessed it was added after your question)

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

Adam
  • 17,838
  • 32
  • 54
0

Negotiation operator needs to check a single value at the next, so if you give like this

!$var = getVar()

the operator onlyapplicable for the next variable so !$var is will seperated. so only we need to give

!($var = getVar())

Sathish Kumar D
  • 274
  • 6
  • 20
  • This is not correct. See the documentation note and the .y grammar rules and the other answers. I show the applied productions here - http://stackoverflow.com/a/32672872/2864740 That is, PHP's grammar is just a bit different then some other languages. – user2864740 Sep 24 '15 at 06:37