rfc:deprecate_dynamic_properties

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
rfc:deprecate_dynamic_properties [2021/08/25 12:50] nikicrfc:deprecate_dynamic_properties [2021/08/25 14:12] nikic
Line 136: Line 136:
 ==== Alternative opt-in to dynamic properties ==== ==== Alternative opt-in to dynamic properties ====
  
-This RFC offers ''extends stdClass'' as a way to opt-in to the use of dynamic properties. Some people have suggested that we could either use a magic marker interface (''implements SupportsDynamicProperties''or an attribute (''#[SupportsDynamicProperties]'') instead.+This RFC offers ''extends stdClass'' as a way to opt-in to the use of dynamic properties. Some people have suggested that we could use a magic marker interface (''implements SupportsDynamicProperties'')an attribute (''#[SupportsDynamicProperties]'') or a trait (''use DynamicProperties;'') instead.
  
-The reasoning behind the ''extends stdClass'' choice is that it is well-defined without introducing any special language support: Imagine that ''stdClass'' implements ''%%__get()%%''/''%%__set()%%'' to provide its "dynamic properties" support. A class extending from ''stdClass'' would naturally inherit this behavior according to normal inheritance semantics. Of course, ''stdClass'' currently doesn'implement magic get/set, but we probably do want to implement them when it comes to dropping engine support for dynamic properties.+The reasoning behind the ''extends stdClass'' choice is that it works without any additional special support: We definitely need to allow dynamic properties on ''stdClass'', and following the Liskov substitution principle, child classes should inherit this behavior. As such, the ''extends stdClass'' escape hatch will work anyway, and the question is more whether we want to offer anything in addition to it. It's also worth noting that it does not require polyfilling on older PHP versions. 
 + 
 +Another way to view this is that ''stdClass'' could implement ''%%__get()%%''/''%%__set()%%'' to provide its "dynamic properties" support, in which case these methods would naturally be inherited. Of course, it currently doesn'do so, but it probably should once dynamic property support is removed.
  
 Using an interface or attribute instead would require the engine to continue supporting dynamic properties on arbitrary classes long term, rather than simply inheriting the behavior from a single class that implements the functionality. Using an interface or attribute instead would require the engine to continue supporting dynamic properties on arbitrary classes long term, rather than simply inheriting the behavior from a single class that implements the functionality.
 +
 +A trait based on ''%%__get()%%''/''%%__set()%%'' could be provided, and would be usable in multiple-inheritance cases where extending from stdClass is not possible:
 +
 +<PHP>
 +class DynamicProperties {
 +    private array $dynamicProps = [];
 +    public function &__get($name) { return $this->dynamicProps[$name]; }
 +    public function __isset($name, $value) { return isset($this->dynamicProps[$name]; }
 +    public function __set($name, $value) { $this->dynamicProps[$name] = $value; }
 +    public function __unset($name) { unset($this->dynamicProps[$name]; }
 +}
 +</PHP>
 +
 +However, such a trait would not differ from simply implementing these methods in userland. Unlike ''extends stdClass'', it would not benefit from optimized internal hooks, and it would not be able to offer exactly the same functionality. A custom implementation does not take a significant amount of code, but has more control over what exactly it wants to support. For example, next to the above baseline implementation, a class might also want to implement ''%%__debugInfo()%%'' and the ''Traversable'' interface.
  
 ==== Opt-out of dynamic properties instead ==== ==== Opt-out of dynamic properties instead ====
Line 151: Line 167:
  
 However, based on the discussion on the language evolution proposal, this would only delay the time where disallowed dynamic properties become the default and only behavior, as there was a strong consensus that diverging language behavior should not be maintained indefinitely. Dynamic properties would ultimately still get deprecated and removed. However, based on the discussion on the language evolution proposal, this would only delay the time where disallowed dynamic properties become the default and only behavior, as there was a strong consensus that diverging language behavior should not be maintained indefinitely. Dynamic properties would ultimately still get deprecated and removed.
 +
 +==== Internal impact ====
 +
 +Internal classes can already specify the ''ZEND_ACC_NO_DYNAMIC_PROPERTIES'' flag to disable dynamic property creation. During the deprecation phase, this RFC is non-intrusive and only adds a ''ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES'' flag to efficiently opt-out stdClass from the deprecation warning. 
 +
 +Once dynamic properties are disallowed, some larger changes should be made. Support for dynamic properties should be dropped from the virtual machine and default object handlers. Instead ''stdClass'' should implement custom object handlers, possibly in conjunction with ''%%__get()%%''/''%%__set()%%'', ''%%__debugInfo()%%'' and ''Traversable'' to present the right userland interface.
 +
 +Objects should no longer store a ''properties'' member, reducing the size of all objects by 8 bytes. The ''get_properties()'' object handler should be dropped. Instead code inspecting all object properties should loop over the ''properties_table'' and use ''properties_info_table'' to map property slots back to their metadata. For example, ''foreach'' over an object would no longer materialize the dynamic properties table (which remains after the loop and dramatically increases the object size) and instead efficiently iterate the property slots.
  
 ===== Vote ===== ===== Vote =====
  
 Yes/No. Yes/No.
rfc/deprecate_dynamic_properties.txt · Last modified: 2021/11/26 13:59 by nikic