Assignment in PHP with bool expression: strange be

2019-07-23 15:42发布

问题:

This question already has an answer here:

  • 'AND' vs '&&' as operator 11 answers

Why is $x true in this statment?

$x = true and false;

I've got the problem with some variables but I could reduce the problem to the primitive boolean values.

Update: As you see in the replies the effect has to do with the operator precedense in PHP. There is also a good explanation about the problem in this question, which I couldn't find in the net before since I didn't know that I have a problem with this and I didn't know that there is a difference between '&&'/'||' and 'and'/'or'.

回答1:

After some search I found out that this is caused by the operator precedence in PHP. The '=' operator is stronger than 'and'.

If you want to get the expected result you have to use braces:

$x = (true and false); //correct: $x is false now!

Without braces the expression is equal to ($x = true) and false; . $x will get the 'true' value. After that the PHP interpreter 'replaces' this assignment with the value that $x has just got. So true and false; remains. And that does not do anything. 'false' is lost and didn't influence the expression.

Be aware that the braces are NOT required if you use '&&' or '||'! They are stronger than '=' and thus stronger than 'and' and 'or'. Strange...

This is different to e.g. $x = 5 + 6; since here '+' is stronger than '=' it will be resolved first. In the end it affects only the boolean operators 'and', 'or' and 'xor'. Only with them you have to watch out.

Note also that this is different compared to other languages like JavaScript or Java. In those languages you don't need the braces since the logical operators are stronger than the equal operator (Operators in JavaScript, Operators in Java).



回答2:

More on this:

$x = true and false;

So we have the following. If you guessed that $x is true, you'd be right. Since = has a higher precedent than and.

Rewriting the expression above it would be equal to this:

 ($x = true) and false;

Here's where it gets funny.

If you were to do:

 $x = true && false;

and you'd guess that $x is true, you'd be wrong. $x is actually false in this case.

The above expression is actually equal to:

$x = (true and false);

Why? Because && has a higher precedent than and.