Bug #76591 [Opn->Nab]: Dynamically-built anonymous classes can have static properties collide
| From: | cmb@php.net | Date: | Sat, 21 Jul 2018 20:53:37 +0000 |
| Subject: | Bug #76591 [Opn->Nab]: Dynamically-built anonymous classes can have static properties collide | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-216385@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=76591&edit=1
ID: 76591
Updated by: cmb@php.net
Reported by: eric at ericstern dot com
Summary: Dynamically-built anonymous classes can have static
properties collide
-Status: Open
+Status: Not a bug
Type: Bug
Package: Class/Object related
Operating System: macOS 10.13
PHP Version: 7.2.7
-Assigned To:
+Assigned To: cmb
Block user comment: N
Private report: N
New Comment:
Seems this ticket can be closed.
Previous Comments:
------------------------------------------------------------------------
[2018-07-06 21:07:34] cmb@php.net
In other words: read ânew class {â¦}â as ânew object of class {â¦}â.
------------------------------------------------------------------------
[2018-07-06 20:17:28] eric at ericstern dot com
Ah, you're absolutely right - I missed that line of the docs.
------------------------------------------------------------------------
[2018-07-06 20:15:44] danack@php.net
fyi - that is the documented behaviour. "All objects created by the same anonymous class
declaration are instances of that very class."
As you say, you can work around it with eval. If it wasn't like this, it would need some
special mechanic to allow statics to work for anonymous classes.
But I agree, moderately surprising behaviour.
------------------------------------------------------------------------
[2018-07-06 19:56:37] eric at ericstern dot com
Description:
------------
The class name produced by
get_class() on an anonymous class can return the same value
for two different anonymous classes, apparently when the new class is on the same line
(e.g. a function/method call returns a new anonymous class). While the name produced by get_class is
documented as "an implementation detail, which should not be relied upon", the behavior
that comes as a result is neither documented nor expected: static properties end up having global
naming collisions
This can result in weird downstream behavior where static methods defined in the anonymous class can
"overlap", and only the most recent definition actually has certain data accessible.
A possible workaround could include the old-fashioned eval-based dynamic definition (like PHPUnit
Mock Objects does), but this should not be necessary, and may not be accessible in some environments
due to restrictions on eval use.
Test script:
---------------
https://3v4l.org/ZSoeI
Expected result:
----------------
Anonymous classes are completely independent of each other; their identifying information (e.g.
generated class name) are not dependent entirely on the point of definition, and their static
properties are in no way interrelated.
Also acceptable, though far less desirable: this behavior is documented as something to be expected,
with a workaround for this use case suggested.
Actual result:
--------------
If two anonymous classes are generated from the same code, their internal names (get_class())
collide and as such they end up exhibiting some singleton-like behavior.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=76591&edit=1