Make WordPress Core

Opened 8 weeks ago

Last modified 4 weeks ago

#60875 new defect (bug)

Handler proposal for known dynamic properties that are initialized and set late only when getting its value

Reported by: hellofromtonya's profile hellofromTonya Owned by:
Milestone: 6.6 Priority: normal
Severity: normal Version:
Component: General Keywords: php82
Focuses: php-compatibility Cc:

Description

As noted in #56034:

Dynamic (non-explicitly declared) properties are deprecated as of PHP 8.2 and are expected to become a fatal error in PHP 9.0, though this last part is not 100% certain yet.

There are multiple instances of known dynamic properties that only get initialized and set when getting their value (i.e. which happens within the __get() magic method).

For example:

While [54133] added #[AllowDynamicProperties] attribute to these classes, that strategy is specifically for unknown dynamic properties and not for known like the above examples.

Strategy

These types of known dynamic properties were intentionally designed to get late / lazily initialized each time code gets the property's value. As this is by design, retaining it must be a priority to ensure not only BC but also to avoid breaking code that depends upon it.

The strategy:

  • Retain the design of each property that is late / lazily initialized.
  • Declare the property on the class as either private or protected visibility.
  • Add __isset() magic method to ensure isset() works correctly (it does not right now). This step is needed for functions like wp_list_pluck() (see #59774).
  • Add __set() and __unset() to have a full set of magic methods, but document both to indicate their behavior gets overwritten the next time getting the property's value.
  • Add wp_trigger_error() with E_USER_DEPRECATED to each of the magic methods for all unknown dynamic properties.

See it in action:

This ticket is to:

  • layout the architectural strategy.
  • identify all Core classes with this type of dynamic property.
  • implement the strategy for each of instance.

References:

Change History (1)

#1 @antonvlasenko
4 weeks ago

One thing I stumbled upon while working on a new PR that implements this proposal is the need to be careful when adding protected and private properties to existing classes that previously only contained public properties (e.g., didn't have any protected/private properties before).

PHP adds a null byte character to the names of protected and private properties when converting an object to an array, and the simplexml_load_string() function throws an error as it can't handle the null byte character.

This code snippet illustrates this behavior: https://3v4l.org/XQL4f#v8.3.6 (change the WP_Term::$data's visibility to private or protected to reproduce the issue).

Note: See TracTickets for help on using tickets.