php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76591 Dynamically-built anonymous classes can have static properties collide
Submitted: 2018-07-06 19:56 UTC Modified: 2018-07-21 20:53 UTC
From: eric at ericstern dot com Assigned: cmb (profile)
Status: Not a bug Package: Class/Object related
PHP Version: 7.2.7 OS: macOS 10.13
Private report: No CVE-ID: None
 [2018-07-06 19:56 UTC] 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.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-07-06 20:15 UTC] 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 20:17 UTC] eric at ericstern dot com
Ah, you're absolutely right - I missed that line of the docs.
 [2018-07-06 21:07 UTC] cmb@php.net
In other words: read “new class {…}” as “new object of class {…}”.
 [2018-07-21 20:53 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2018-07-21 20:53 UTC] cmb@php.net
Seems this ticket can be closed.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Sat Jul 04 17:01:28 2020 UTC