Bug #70437 [Com]: Changes to static properties in trait methods are not reflected in the class

From: 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

« previous php.bugs (#199674) next »