Req #75179 [Opn->Sus]: Remove undocumented assignment operator precedence change
Edit report at https://bugs.php.net/bug.php?id=75179&edit=1
ID: 75179
Updated by: cmb@php.net
Reported by: codedokode at gmail dot com
Summary: Remove undocumented assignment operator precedence
change
-Status: Open
+Status: Suspended
Type: Feature/Change Request
Package: Scripting Engine problem
Operating System: Windows XP
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
Thank you for your interest in PHP and for submitting a feature
request. Please be aware that due to the magnitude of change this
request requires, it would be necessary to discuss it on PHP
Internals list (internals@lists.php.net) as an RFC. Please read
the guide about creating RFCs here:
<https://wiki.php.net/rfc/howto>. If you
haven't had experience
with writing RFCs before, it is advised to seek guidance on the
Internals list (<http://php.net/mailing-lists.php>) and/or solicit
help from one of the experienced developers.
Please do not consider this comment as a negative view on the
merits of your proposal â every proposal which requires changes of
certain magnitude, even the very successful and widely supported
ones, must be done through the RFC process. This helps make the
process predictable, transparent and accessible to all developers.
Previous Comments:
------------------------------------------------------------------------
[2017-09-10 14:28:07] cmb@php.net
> 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.
No, this is actually the PHP language specification to which the
php.net PHP implementation is supposed to conform.
------------------------------------------------------------------------
[2017-09-10 11:44:21] codedokode at gmail dot com
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 this bug report at https://bugs.php.net/bug.php?id=75179&edit=1
Thread (4 messages)