PHP 8.2 Deprecation of Dynamic Properties
With the release of PHP 8.2 in November 2022, Phalcon and in particular Zephir were adjusted accordingly to support the new code and generate the correct module for this new PHP release.
Everything has been working as expected, all the tests were passing, until our community members reported some deprecation warnings appearing in their logs.
In particular, this was appearing in several spots of the application (or similar messages)
Deprecated: Creation of dynamic property Phalcon\Mvc\View\Engine\Volt::$tag is deprecated in...
History
In the past, developers could very easily create and assign properties in classes on the fly. This means that the following code was perfectly fine:
<?php
class Invoices
{
public string $inv_id = 0;
}
// ....
$invoice = new Invoices();
$invoice->inv_id = 1234;
// inv_number does not exist in the class
$invoice->inv_number = 'INV-1234';
Utilizing __get()
and __set()
in your class, you could prevent that behavior, but it was never enforced. With PHP 8.2 we not get a deprecation warning, and in PHP 9 this will become a fatal error.
Why?
Dynamic properties have been a great feature in PHP, but at the same time pandora’s box. A simple typo in a statement (and I should know, I have had my share of those through the years) could assign data to the wrong variable and have consequences for the application. Such errors/typos could go unnoticed for a long time, until the application would start behaving in a weird way. Of course the testing suite should catch that but not all applications have 100% test coverage, and sadly many applications do not have any tests at all.
Frameworks, such as Phalcon rely on dynamic properties to assign data to the view engine, or to the ORM, or to the DI container.
What now?
Until PHP 9.0 becomes the norm, we have to adjust our code to avoid the deprecation warnings and rewrite parts of our framework/application to avoid the dynamic properties.
We have three potential solutions for this deprecation (other than fully refactoring our code).
AllowDynamicProperties attribute
The #[AllowDynamicProperties]
attribute introduced in PHP 8.2, we can instruct PHP to stop emitting this deprecation notice. Even child classes of that class will inherit this behavior.
<?php
#[AllowDynamicProperties]
class Invoices
{
public string $inv_id = 0;
}
// ....
$invoice = new Invoices();
$invoice->inv_id = 1234;
// inv_number does not exist in the class
$invoice->inv_number = 'INV-1234';
stdClass
and its children
stdClass
already has #[AllowDynamicProperties]
attribute defined, so extending stdClass
would allow dynamic properties
<?php
use stdClass;
class Invoices extends stdClass
{
public string $inv_id = 0;
}
// ....
$invoice = new Invoices();
$invoice->inv_id = 1234;
// inv_number does not exist in the class
$invoice->inv_number = 'INV-1234';
__get()
and __set()
If a class has the __set()
(and eventually the __get()
) magic methods defined, the deprecation warning will not be emitted.
<?php
use stdClass;
class Invoices extends stdClass
{
public string $inv_id = 0;
public function __set(string $name, mixed $value): void
{
}
}
// ....
$invoice = new Invoices();
$invoice->inv_id = 1234;
// inv_number does not exist in the class
$invoice->inv_number = 'INV-1234';
A much easier way to deal with this would be to use an internal array to handle the dynamic properties, in combination with __get()
and __set()
:
<?php
class Invoices
{
private array $store = [];
public function __get(string $name): mixed
{
return $this->store[$name] ?? null;
}
public function __set(string $name, mixed $value): void
{
$this->store[$name] = $value;
}
}
// ....
$invoice = new Invoices();
$invoice->inv_id = 1234;
$invoice->inv_number = 'INV-1234';
Phalcon
To avoid the issue above, we changed the Phalcon\Di\Injectable
to extend stdClass
. This also was the case for Phalcon\Mvc\Model\Row
which represents records for the ORM.
Ideally, we would have loved to be able to rewrite our code so that we do not have any issues in the future. Storing the data in an internal array, offers the flexibility of dynamic properties and gets rid of the deprecation warnings.
To add the #[AllowDynamicProperties]
annotation in Zephir would be a nightmare, and it will require a lot of work, so the stdClass
solution was the best one.
The fix was here
-
Nikolaos Dimopoulos
Boldly goes where no other coder has gone before.... and other ramblings
Recent Posts
-
Setting up Docker for Qubes OS
2024-10-05 -
PhpStorm cannot create scratch files
2023-12-07 -
PHP 8.2 Deprecation of Dynamic Properties
2023-07-18 -
New Look
2023-06-12 -
Linux Swap file in RAM
2023-04-17
Tag Cloud
-
amazon (3)
android (1)
angularjs (7)
apps (1)
aurora (1)
aws (1)
backup (2)
bash (1)
bitbucket (1)
blog (2)
books (1)
bootstrap (1)
buzz (1)
cPanel (1)
cache (1)
celebrations (4)
chromium (3)
chromium os (3)
cloud computing (3)
codacy (1)
codecov (1)
communications (1)
composer (1)
conversion (1)
copy (1)
degoogle (5)
design (1)
design patterns (3)
discord (1)
docker (1)
docs (3)
documentation (1)
ec2 (3)
emerge (1)
encoding (1)
factory (1)
froyo (1)
fujitsu (1)
gentoo (7)
git (3)
github (2)
gmail (3)
google (16)
google apps (4)
google maps (1)
gource (1)
ha (1)
hosting (2)
how to (36)
igbinary (1)
information (5)
input (1)
installation (6)
internet (1)
iphone (1)
json (2)
libreoffice (1)
linux (13)
localization (1)
lts (1)
mariadb (1)
memorial day (1)
metrics (1)
migration (1)
mod_rewrite (1)
mov (1)
mp4 (1)
mysql (6)
nas (1)
netlify (1)
new look (1)
nexus one (2)
nfs (1)
notebook (1)
online storage (1)
openoffice (1)
opinion (1)
oracle (1)
patterns (1)
payroll (1)
performance (3)
personal (9)
phalcon (12)
php (23)
php8 (2)
php82 (1)
phpstorm (1)
phpunit (2)
picasa (2)
portage (1)
privacy (1)
programming (9)
proxy (1)
qubes os (1)
rant (5)
rdbms (1)
rds (1)
relationships (1)
release (1)
remove (1)
replication (1)
review (9)
rsync (2)
s1300 (1)
scan (1)
scratch (1)
serialize (1)
series (9)
singleton (1)
sorting (1)
spaceship (1)
spam (1)
ssl (1)
static (1)
storage (6)
submodules (1)
subversion (2)
svn (1)
swap (1)
tdd (1)
technorati (1)
test driven development (1)
testability (1)
testing (2)
titles (1)
traits (1)
ua (1)
ubuntu (1)
update (6)
upgrade (1)
usa (2)
usort (1)
utf8 (1)
video (1)
visualization (1)
vps (1)
webm (1)
website (1)
wget (1)
zend framework (4)
zram (1)
zstd (1)