Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP 8.2 Dynamic Properties Deprecated: how to use them anyway in a compatible way

Tags:

php

In PHP 8.2, Dynamic Properties are deprecated, and will result in a fatal error from PHP 9 onwards.

Using Dynamic Properties on Classes running PHP 8.2 will lead to PHP Deprecated: Creation of dynamic property is deprecated E_DEPRECATED warnings.

Now, while this is generally a bad OO practice to have public/dynamic properties in a Class, this question is not about the best OO practice but instead, how to make actual code that uses Dynamic Properties compatible with PHP 8.2 onwards.

How to make actual codebases that make use of Dynamic Properties compatible with the new behaviour?

like image 743
Maurizio Avatar asked Nov 21 '25 23:11

Maurizio


1 Answers

As suggested by ADyson, the solution is to use the #[AllowDynamicProperties] attribute just above the class definition.

Classes marked with #[AllowDynamicProperties] as well as their children can continue using dynamic properties without deprecation or removal.

For classes that intentionally don't have a fixed set of properties, it's possible to either implement magic __get()/__set() or mark the class using the #[AllowDynamicProperties] attribute. Marking a class with #[AllowDynamicProperties] is fully backwards-compatible with earlier PHP versions, because prior to PHP 8.0 this would be interpreted as a comment, and the use non-existent classes as attributes is not an error.

This is a full example, as contained in this github repository that I've created to test this feature on Traits and Extended Classes

<?php
namespace App\Classes;

/**
 * Use the fully-qualified AllowDynamicProperties, otherwise the #[AllowDynamicProperties] attribute on "MyClass" WILL NOT WORK.
 */
use \AllowDynamicProperties;

#[AllowDynamicProperties]
class MyClass
{
    /**
     * Dynamic attributes will work with no deprecation warnings
     */
    public function __construct()
    {
        $this->first_name = 'George';
        $this->last_name = 'Orwell';
    }
}

class MyExtendedClass extends MyClass 
{
    /**
     * Even if "MyExtendedClass" is not using #[AllowDynamicProperties], it extends "MyClass", that is using it.
     * Dynamic attributes will work with no deprecation warnings
     */
    public function __construct()
    {
        parent::__construct();
    }
}

Other noteworthy facts:

  • If you're willing to use the #[AllowDynamicProperties] attribute in non-namespaced contexts, the fully-qualified use \AllowDynamicProperties; statement is not strictly needed (this extends the comment of user706420)
  • If you need a quick and dirty fix (for example, an old codebase) you can use the class Foo extends \stdClass as suggested by Ale DC: dynamic properties will work as expected.
like image 86
Maurizio Avatar answered Nov 24 '25 15:11

Maurizio



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!