Req #75179 [NEW]: Remove undocumented assignment operator precedence change

From: Date: Sun, 10 Sep 2017 11:44:34 +0000
Subject: Req #75179 [NEW]: Remove undocumented assignment operator precedence change
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-211023@lists.php.net to get a copy of this message
From: codedokode at gmail dot com Operating system: Windows XP PHP version: Irrelevant Package: Scripting Engine problem Bug Type: Feature/Change Request Bug description:Remove undocumented assignment operator precedence change Description: ------------ Accidently I found out that PHP allows ambiguous expressions like this: $a + $b = 1; Documentation states that plus operator has higher precedence than assignment operator (which is the case for similar expression $a = 1 + 2), therefore I expected the code to produce a syntax error, but there were only warnings about undefined variables [1] I googled around and found out that there are some undocumented hacks in the parser that make it ignore operator precedence in assignment. They are not documented, the documentation [2] only mentions that "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.". There is no clear description, what types of invalid expressions are allowed, and how they are interpreted. I also checked PHP language spec by Facebook [3] and didn't found there anything about this feature. I understand that is a third-party specification but there seems to be no any other specifications. I found several bugs where a similar question was asked: bug #17386, bug #63825, bug #40820. It looks like PHP tries to "guess" author's intent and "fix" the code. In all those bugs PHP developers confirmed that this behaviour was intended. As it turned out, PHP can also change precedence even in expressions without assignment operator: bug #73802 I think this is wrong because: - the rules for changing precedence are not documented, it is unclear what result the code will produce. - there are alternative PHP implementations (like HHVM) that will probably not support this transformation, therefore the same code might work differently in different PHP implementations. - PHP is unable to guess author's original intent and producing a clear syntax error message will help author to find the reason of error faster rather than pretending that the code is correct and confusing the author - when static analysis tools find expression like $a + $b = 1, they cannot state that this is a mistake because this code in fact works For example, I saw a code where the author thought that assignment target is written on the right and wrote a line like $a + $b = $c. PHP interpreted the expression as ($a + ($b = $c)) but the original intent was $c = $a + $b. We see that the "fix" by PHP parser only have confused the author and a syntax error message would be much more useful in this case. The use cases where this behaviour might be useful like if (!$a = fn()), are rare. My suggestions are: - admit that the parser is unable to guess author's original intent and this behaviour is undesirable in future versions of PHP - add a warning or deprecation notice when precedence is changed by the parser with clear description of the problem - remove precedence changing in some future PHP version and produce syntax errors If we don't start producing warnings, authors will continue to write such code and even many years later PHP developers (and maybe developers of alternative implementations) will have to support this undocumented feature. If necessary, I could try to make the pull request myself, but later when I have time for this. This bug can be assigned a low priority. [1] https://3v4l.org/ATpvW [2] http://php.net/manual/en/language.operators.precedence.php [3] https://github.com/php/php-langspec/blob/master/spec/10-expressions.md#assignment-operators Test script: --------------- <?php // https://3v4l.org/ATpvW $a + $b = 1; Expected result: ---------------- Syntax error Actual result: -------------- No syntax error -- Edit bug report at https://bugs.php.net/bug.php?id=75179&edit=1 -- Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=75179&r=trysnapshot54 Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=75179&r=trysnapshot55 Try a snapshot (trunk): https://bugs.php.net/fix.php?id=75179&r=trysnapshottrunk Fixed in SVN: https://bugs.php.net/fix.php?id=75179&r=fixed Fixed in release: https://bugs.php.net/fix.php?id=75179&r=alreadyfixed Need backtrace: https://bugs.php.net/fix.php?id=75179&r=needtrace Need Reproduce Script: https://bugs.php.net/fix.php?id=75179&r=needscript Try newer version: https://bugs.php.net/fix.php?id=75179&r=oldversion Not developer issue: https://bugs.php.net/fix.php?id=75179&r=support Expected behavior: https://bugs.php.net/fix.php?id=75179&r=notwrong Not enough info: https://bugs.php.net/fix.php?id=75179&r=notenoughinfo Submitted twice: https://bugs.php.net/fix.php?id=75179&r=submittedtwice register_globals: https://bugs.php.net/fix.php?id=75179&r=globals PHP 4 support discontinued: https://bugs.php.net/fix.php?id=75179&r=php4 Daylight Savings: https://bugs.php.net/fix.php?id=75179&r=dst IIS Stability: https://bugs.php.net/fix.php?id=75179&r=isapi Install GNU Sed: https://bugs.php.net/fix.php?id=75179&r=gnused Floating point limitations: https://bugs.php.net/fix.php?id=75179&r=float No Zend Extensions: https://bugs.php.net/fix.php?id=75179&r=nozend MySQL Configuration Error: https://bugs.php.net/fix.php?id=75179&r=mysqlcfg

« previous php.bugs (#211023) next »