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.