[php-src] Issue #8152: Cannot hydrate a DateTime instance created without the constructor
| From: | nicolas-grekas | Date: | Thu, 24 Feb 2022 21:30:11 +0000 |
| Subject: | [php-src] Issue #8152: Cannot hydrate a DateTime instance created without the constructor | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-240020@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/8152
Author: nicolas-grekas
### Description
This report applies to DateTime, DateTimeImmutable, DateTimeZone, DateInterval and DatePeriod.
Before PHP 8.2, there used to be a way to create a DateTime object from an uninitialized prototype:
```php
$date = (new \ReflectionClass('DateTime'))->newInstanceWithoutConstructor();
$date->date = '1970-01-01 00:00:00.000000';
$date->timezone_type Warning: Undefined property: DateTime::$date in /in/EUrC5 on line 4
NULL
string(26) "2022-02-24 22:26:25.005040"= 1;
$date->timezone = '+00:00';
$date->__wakeup();
```
These 3 properties do not exist on
DateTime, but they're still returned by
serialize($date), that's how I figured out how to hydrate the previous object. And
it works perfectly. But since PHP 8.2, a deprecation is triggered because dynamic properties are not
allowed.
Since means that since 8.2, there is no way to hydrate a DateTime instance that is
created without the constructor.
This is an issue in symfony/var-exporter for example, which is a library that provides a way to
serialize objects to native PHP code (instead of the serialization format). I cannot figure out a
way to make this lib support PHP 8.2 while not triggering a warning.
Not that the engine allows itself to create those dynamic properties even on PH P8.2. Here is some
code to highlight this:
```php
$d = new DateTime();
var_dump($d->date);
$e = unserialize(serialize($d));
var_dump($e->date);
```
This [outputs](https://3v4l.org/EUrC5/rfc#vgit.master):
```
Warning: Undefined property: DateTime::$date in /in/EUrC5 on line 4
NULL
string(26) "2022-02-24 22:26:25.005040"
```
A simple fix would be to add #[AllowDynamicProperties] to those classes.
Another fix would be to actually declare the corresponding properties as protected.
WDYT?