Reputation: 920
As of version 8.0, PHP has gained the ability to add attributes to various entities.
With PHP 8.2, creating dynamic properties has been deprecated: attempting to set a property on a class that does not have that property explicitly declared now yields a deprecation notice, and from PHP 9.0 will throw a fatal error.
In order to avoid this, the documentation says that classes should either use __get()
and __set()
to store ‘dynamic’ properties in a pre-declared array in the class (which is a workaround that has nothing to do with dynamic properties and solves nothing), or apply the AllowDynamicProperties
attribute to the class.
The documentation says that attributes can be applied to classes, methods, functions, parameters, properties and class constants – notably omitting traits and interfaces. The original RFC, conversely, includes traits and interfaces.
In practice, it seems that userland attributes can be declared on traits and interfaces (i.e., they are not invalid code), but they are not actually applied when using/implementing the trait/interface in an instantiating class (i.e., the instance does not see the attributes). Attributes declared on properties inside a trait, conversely, do get applied and are available in the class instance.
With native attributes, things work differently: at least some of them – such as AllowDynamicProperties
– are actively prohibited from being even declared in traits/interfaces (cf. this GitHub comment). This throws a fatal error:
#[\AllowDynamicProperties]
trait MyTrait {}
I can see why an attribute like this – or perhaps attributes in general – would not be desirable for an interface which, after all, provides no independent functionality and is exclusively a contract. So let’s leave interfaces on the side.
But to the extent that dynamic properties have value (and I think they do), I cannot see any reason why they should have less value in a trait than in a class. Traits can provide functionality that requires dynamic properties just as well as classes can.
Similarly, I don’t see any logical reason why attributes declared on traits should not be applied when instantiating a class that uses that trait, particularly when attributes on trait properties are applied.
So my question is two-fold: what is the logic behind (and/or the benefits of)
AllowDynamicProperties
, to be declared on traits?Upvotes: 0
Views: 745
Reputation: 27011
Traits cannot have instance properties, so applying this attribute is meaningless. Perhaps you expect that all the classes using the trait can automatically obtain this attribute, but using trait isn't equivalent to inheritance. To do so you need to write addtional code. Since this is already a deprecated feature and will be removed in the next version, it doesn't seem necessary to do this.
Upvotes: 0