Bug #70437 [Com]: Changes to static properties in trait methods are not reflected in the class
| From: | eric at ericstern dot com | Date: | Tue, 08 Mar 2016 20:53:39 +0000 |
| Subject: | Bug #70437 [Com]: Changes to static properties in trait methods are not reflected in the class | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-199674@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=70437&edit=1
ID: 70437
Comment by: eric at ericstern dot com
Reported by: davey@php.net
Summary: Changes to static properties in trait methods are
not reflected in the class
Status: Assigned
Type: Bug
Package: Scripting Engine problem
Operating System: OSX/Linux
PHP Version: 7.0.0RC2
Assigned To: bwoebi
Block user comment: N
Private report: N
New Comment:
I'm experiencing this (or at least something very similar) as well, and have some additional
information which may or may not be relevant:
If you call a static method that sets a property on the trait before a class uses it, that property
is copied across. If the class is what triggers the trait to load and that same setter is called
after the class using the trait is loaded (but still before access to that property), the value is
null. Basically, the autoload order matters.
While the examples below may not quite follow the original RFC's intent, I think it's
fairly obvious what the code's intent is (conceivably, setting the same static property on all
classes that use a given trait)
Interestingly, trying to use the trait's name instead of self errors out with invalid property
access, even though the intent is *even* more obviously to get the value out of the trait. This case
has completely unambiguous intent, but fails the worst.
Null property: https://3v4l.org/4pXor
Works as expected: https://3v4l.org/428lo
Access not allowed: https://3v4l.org/Lk3ll
tl;dr:
self doesn't really work as an end-user would expect in traits. Maybe it
should have been prevented outright in the initial design, but that ship has sailed. As someone just
writing code (and not PHP internals), I expect static properties defined in traits to be shared
across everything using that trait, even though that's not semantically in line with
"compiler-assisted copy and paste"
For context, the main use case (for me) is to avoid injecting the same configuration change in
thirty places, which is totally in line with the actual intent of using traits to write DRY code.
Previous Comments:
------------------------------------------------------------------------
[2015-09-07 11:10:56] bwoebi@php.net
Is it by design?
We don't know, it's neither documented nor mentioned in the original RFC.
Heck, the RFC itself proposed even a singleton trait.
With current semantics that trait could be used only exactly once, because the trait shares the
static property. I guess that's not the purpose of traits, it's about horizontal *reuse*.
Hence each class should have its own static properties and never use the static property of the
trait.
Also, by the way, if they were supposed to be independent, then the classes shouldn't be copied
the traits static properties (and methods too) into them.
We should have one or the other behavior, but having both behaviors is very confusing.
------------------------------------------------------------------------
[2015-09-07 11:02:00] gron@php.net
This is by design, changing that is a BC issue.
The design is chosen based on the desired 'copy-down' semantics of traits.
Static properties of traits are independent of the ones of classes using the trait.
Changing it means you break the copy-down semantics by adding another corner case where it is not
consistent.
------------------------------------------------------------------------
[2015-09-07 10:45:15] bwoebi@php.net
Did you checkout the patch? It's always accessing the class' static property now as far as
I see?
------------------------------------------------------------------------
[2015-09-07 10:39:25] davey@php.net
The issue isn't when calling the method directly on the trait but also when calling it on the
implementing class. Any changes to static properties within trait methods called on the implementing
class are only reflected within the traits copy of it; rather than the implementing classes copy as
it should be.
------------------------------------------------------------------------
[2015-09-07 09:15:15] bwoebi@php.net
Totally agreeing with Nikita here; I've just attached a small PR: https://github.com/php/php-src/pull/1506
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=70437
--
Edit this bug report at https://bugs.php.net/bug.php?id=70437&edit=1