This utility is intended to showcase what's contained in the PHP 8.2 AllowDynamicProperties RFC.
This is to avoid Deprecation Warnings on PHP 8.2 when using Dynamic Properties: PHP Deprecated: Creation of dynamic property Class::$attribute is deprecated
.
This repository is intended to show how to globally solve the PHP Deprecated: Creation of dynamic property is deprecated
with minor code changes, thus allowing dynamic properties with no warnings.
To make a Class compatible with Dynamic Attributes, follow the below example, that is purposedly using a namespace.
Pay attention: in a project using namespaced classes, you will HAVE TO add the
use \AllowDynamicProperties;
to make this work. Otherwise, PHP won't know what "AllowDynamicProperties" is. Under the hoods, in fact, the attribute set above the Class definition is using The AllowDynamicProperties class, that really is a Final Class itself.
<?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();
}
}
In PHP 8.2 and later, setting a value to an undeclared class property is deprecated, and emits a deprecation notice the first time the property is set during the lifetime of the application execution. There are legitimate use cases of dynamic properties, such as value objects derived from a dynamic JSON response, or configuration objects that allow arbitrary values. (reference: php.watch)
IMHO, Deprecating dynamic properties sucks. The votation of 2021-11-26 finished with a favor of 52 votes, with only 25 that were not convinced (as I am.)
Anyway, the #[AllowDynamicProperties] attribute is an effective workaround to let this feature work and not trigger any E_DEPRECATED warnings.
The tests are intended to let the reader know how to implement the #[AllowDynamicProperties] in various scenarios.
You'll have to use PHP 8.2 binary. Here is the list of steps to run all the tests.
composer install
/usr/bin/php8.2 test --verbose all
to run all the tests in verbose mode (dumps objects)/usr/bin/php8.2 test all
to run all the tests/usr/bin/php8.2 test [deprecated|allowDynamicPropertiesTest1|allowDynamicPropertiesTest1OnExtended|allowDynamicPropertiesTest2|allowDynamicPropertiesTest2OnExtended]
to specifically run a single test
If you only want a readable, simple, single-file test that showcases everything, use showcase.php
:
/usr/bin/php8.2 showcase.php
deprecated
: you will getE_DEPRECATED
warningsallowDynamicPropertiesTest1
: you shold not getE_DEPRECATED
warnings. Dynamic Properties are set within the class constructor.allowDynamicPropertiesTest1OnExtended
: you shold not getE_DEPRECATED
warnings. This test extends theAllowDynamicPropertiesTest1
class.allowDynamicPropertiesTest2
: you should not getE_DEPRECATED
warnings. Dynamic Properties are set via calling a specificsetProps()
method.allowDynamicPropertiesTest2OnExtended
: you should not getE_DEPRECATED
warnings. This test extends theAllowDynamicPropertiesTest2
class.stackOverflowUser706420Test
: you will getE_DEPRECATED
warnings. This test is intended to demonstrate that StackOverflow's user706420 is not correct in his comment left here: in fact, his statement is true only on non-namespaced contexts. In a namespaced context, you'll always need the fully-qualifieduse \AllowDynamicProperties;
statement.