PHP operator precedence bug?

2020-02-11 04:05发布

问题:

The result of:

var_dump(null != $a = 15);
var_dump($a);

is:

bool(true)
int(15)

Why is this script not triggering an error? Since != (not equal operator) has a higher precedence than = (assignment operator), $a should be compared to null first?

回答1:

The only reason I can find is that the documentation says that this is still legal: http://php.net/manual/en/language.operators.precedence.php#example-129

It seems to be an exception to what is shown in the table above.



回答2:

This is not about operator precedence but about: operator precedence lists don't tell you the details (really, they never do), e.g. about the bison rules and the resulting pattern matching and stack reducing.
Let's take the statement null != $a = 15;, for simplicity without the var_dump.
This is how the parser "sees" this statement - or: sees that it is a statement.
(I hope this will be rendered with a fix-width font everywhere...)

null                       !=                    $a                                  =   15                           ;
                                                 T_VARIABLE                           
identifier                                       compound_variable                       T_LNUMBER
namespace_name                                   reference_variable                      common_scalar
general_constant                                 base_variable                           scalar
scalar                                           base_variable_with_functions_calls      expr_without_variable
expr_without_variable                            variable                            =   expr
expr                       T_IS_NOT_EQUAL             \______ expr_without_variable _________/
   \__________________    expr ____________________________________________/                                          ;
                           \_________________       unticked_statement _______________________________________________/
                                                     statement                                 

( You can look up the rules at https://github.com/php/php-src/blob/PHP-5.6.15/Zend/zend_language_parser.y )

There's no special rule for the assignment operator in this case; there simply isn't another way for the parser to match the statement, so precedence doesn't apply.