Skip to content

Commit c4bfc55

Browse files
Fix deprecations on PHP 8.2
1 parent 70efd49 commit c4bfc55

File tree

7 files changed

+174
-63
lines changed

7 files changed

+174
-63
lines changed

Internal/Exporter.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,15 @@ public static function prepare($values, $objectsPool, &$refsPool, &$objectsCount
108108
}
109109
$properties = ['SplObjectStorage' => ["\0" => $properties]];
110110
$arrayValue = (array) $value;
111-
} elseif ($value instanceof \Serializable || $value instanceof \__PHP_Incomplete_Class) {
111+
} elseif ($value instanceof \Serializable
112+
|| $value instanceof \__PHP_Incomplete_Class
113+
|| $value instanceof \DatePeriod
114+
|| (\PHP_VERSION_ID >= 80200 && (
115+
$value instanceof \DateTimeInterface
116+
|| $value instanceof \DateTimeZone
117+
|| $value instanceof \DateInterval
118+
))
119+
) {
112120
++$objectsCount;
113121
$objectsPool[$value] = [$id = \count($objectsPool), serialize($value), [], 0];
114122
$value = new Reference($id);

Internal/Hydrator.php

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -55,45 +55,14 @@ public static function hydrate($objects, $values, $properties, $value, $wakeups)
5555

5656
public static function getHydrator($class)
5757
{
58-
if ('stdClass' === $class) {
59-
return self::$hydrators[$class] = static function ($properties, $objects) {
60-
foreach ($properties as $name => $values) {
61-
foreach ($values as $i => $v) {
62-
$objects[$i]->$name = $v;
63-
}
64-
}
65-
};
66-
}
67-
68-
if (!class_exists($class) && !interface_exists($class, false) && !trait_exists($class, false)) {
69-
throw new ClassNotFoundException($class);
70-
}
71-
$classReflector = new \ReflectionClass($class);
72-
73-
if (!$classReflector->isInternal()) {
74-
return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, $class);
75-
}
76-
77-
if ($classReflector->name !== $class) {
78-
return self::$hydrators[$classReflector->name] ?? self::getHydrator($classReflector->name);
79-
}
80-
8158
switch ($class) {
82-
case 'ArrayIterator':
83-
case 'ArrayObject':
84-
$constructor = \Closure::fromCallable([$classReflector->getConstructor(), 'invokeArgs']);
85-
86-
return self::$hydrators[$class] = static function ($properties, $objects) use ($constructor) {
59+
case 'stdClass':
60+
return self::$hydrators[$class] = static function ($properties, $objects) {
8761
foreach ($properties as $name => $values) {
88-
if ("\0" !== $name) {
89-
foreach ($values as $i => $v) {
90-
$objects[$i]->$name = $v;
91-
}
62+
foreach ($values as $i => $v) {
63+
$objects[$i]->$name = $v;
9264
}
9365
}
94-
foreach ($properties["\0"] ?? [] as $i => $v) {
95-
$constructor($objects[$i], $v);
96-
}
9766
};
9867

9968
case 'ErrorException':
@@ -122,6 +91,38 @@ public static function getHydrator($class)
12291
};
12392
}
12493

94+
if (!class_exists($class) && !interface_exists($class, false) && !trait_exists($class, false)) {
95+
throw new ClassNotFoundException($class);
96+
}
97+
$classReflector = new \ReflectionClass($class);
98+
99+
switch ($class) {
100+
case 'ArrayIterator':
101+
case 'ArrayObject':
102+
$constructor = \Closure::fromCallable([$classReflector->getConstructor(), 'invokeArgs']);
103+
104+
return self::$hydrators[$class] = static function ($properties, $objects) use ($constructor) {
105+
foreach ($properties as $name => $values) {
106+
if ("\0" !== $name) {
107+
foreach ($values as $i => $v) {
108+
$objects[$i]->$name = $v;
109+
}
110+
}
111+
}
112+
foreach ($properties["\0"] ?? [] as $i => $v) {
113+
$constructor($objects[$i], $v);
114+
}
115+
};
116+
}
117+
118+
if (!$classReflector->isInternal()) {
119+
return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, $class);
120+
}
121+
122+
if ($classReflector->name !== $class) {
123+
return self::$hydrators[$classReflector->name] ?? self::getHydrator($classReflector->name);
124+
}
125+
125126
$propertySetters = [];
126127
foreach ($classReflector->getProperties() as $propertyReflector) {
127128
if (!$propertyReflector->isStatic()) {

Tests/Fixtures/array-object.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
44
$o = [
5-
clone (($p = &\Symfony\Component\VarExporter\Internal\Registry::$prototypes)['ArrayObject'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('ArrayObject')),
6-
clone $p['ArrayObject'],
5+
clone (($p = &\Symfony\Component\VarExporter\Internal\Registry::$prototypes)['Symfony\\Component\\VarExporter\\Tests\\ArrayObject'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('Symfony\\Component\\VarExporter\\Tests\\ArrayObject')),
6+
clone ($p['ArrayObject'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('ArrayObject')),
77
],
88
null,
99
[],

Tests/Fixtures/datetime-legacy.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
4+
$o = \Symfony\Component\VarExporter\Internal\Registry::unserialize([
5+
clone (($p = &\Symfony\Component\VarExporter\Internal\Registry::$prototypes)['DateTime'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('DateTime')),
6+
clone ($p['DateTimeImmutable'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('DateTimeImmutable')),
7+
clone ($p['DateTimeZone'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('DateTimeZone')),
8+
clone ($p['DateInterval'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('DateInterval')),
9+
], [
10+
4 => 'O:10:"DatePeriod":6:{s:5:"start";O:8:"DateTime":3:{s:4:"date";s:26:"2012-07-01 00:00:00.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}s:7:"current";N;s:3:"end";N;s:8:"interval";O:12:"DateInterval":16:{s:1:"y";i:0;s:1:"m";i:0;s:1:"d";i:7;s:1:"h";i:0;s:1:"i";i:0;s:1:"s";i:0;s:1:"f";d:0;s:7:"weekday";i:0;s:16:"weekday_behavior";i:0;s:17:"first_last_day_of";i:0;s:6:"invert";i:0;s:4:"days";b:0;s:12:"special_type";i:0;s:14:"special_amount";i:0;s:21:"have_weekday_relative";i:0;s:21:"have_special_relative";i:0;}s:11:"recurrences";i:5;s:18:"include_start_date";b:1;}',
11+
]),
12+
null,
13+
[
14+
'stdClass' => [
15+
'date' => [
16+
'1970-01-01 00:00:00.000000',
17+
'1970-01-01 00:00:00.000000',
18+
],
19+
'timezone_type' => [
20+
1,
21+
1,
22+
3,
23+
],
24+
'timezone' => [
25+
'+00:00',
26+
'+00:00',
27+
'Europe/Paris',
28+
],
29+
'y' => [
30+
3 => 0,
31+
],
32+
'm' => [
33+
3 => 0,
34+
],
35+
'd' => [
36+
3 => 7,
37+
],
38+
'h' => [
39+
3 => 0,
40+
],
41+
'i' => [
42+
3 => 0,
43+
],
44+
's' => [
45+
3 => 0,
46+
],
47+
'f' => [
48+
3 => 0.0,
49+
],
50+
'weekday' => [
51+
3 => 0,
52+
],
53+
'weekday_behavior' => [
54+
3 => 0,
55+
],
56+
'first_last_day_of' => [
57+
3 => 0,
58+
],
59+
'invert' => [
60+
3 => 0,
61+
],
62+
'days' => [
63+
3 => false,
64+
],
65+
'special_type' => [
66+
3 => 0,
67+
],
68+
'special_amount' => [
69+
3 => 0,
70+
],
71+
'have_weekday_relative' => [
72+
3 => 0,
73+
],
74+
'have_special_relative' => [
75+
3 => 0,
76+
],
77+
],
78+
],
79+
[
80+
$o[0],
81+
$o[1],
82+
$o[2],
83+
$o[3],
84+
$o[4],
85+
],
86+
[
87+
1 => 0,
88+
1,
89+
2,
90+
3,
91+
]
92+
);

Tests/Fixtures/datetime.php

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,21 @@
11
<?php
22

33
return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
4-
$o = [
5-
clone (\Symfony\Component\VarExporter\Internal\Registry::$prototypes['DateTime'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('DateTime')),
6-
],
4+
$o = \Symfony\Component\VarExporter\Internal\Registry::unserialize([], [
5+
'O:8:"DateTime":3:{s:4:"date";s:26:"1970-01-01 00:00:00.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}',
6+
'O:17:"DateTimeImmutable":3:{s:4:"date";s:26:"1970-01-01 00:00:00.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}',
7+
'O:12:"DateTimeZone":2:{s:13:"timezone_type";i:3;s:8:"timezone";s:12:"Europe/Paris";}',
8+
'O:12:"DateInterval":16:{s:1:"y";i:0;s:1:"m";i:0;s:1:"d";i:7;s:1:"h";i:0;s:1:"i";i:0;s:1:"s";i:0;s:1:"f";d:0;s:7:"weekday";i:0;s:16:"weekday_behavior";i:0;s:17:"first_last_day_of";i:0;s:6:"invert";i:0;s:4:"days";b:0;s:12:"special_type";i:0;s:14:"special_amount";i:0;s:21:"have_weekday_relative";i:0;s:21:"have_special_relative";i:0;}',
9+
'O:10:"DatePeriod":6:{s:5:"start";O:8:"DateTime":3:{s:4:"date";s:26:"2012-07-01 00:00:00.000000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";}s:7:"current";N;s:3:"end";N;s:8:"interval";O:12:"DateInterval":16:{s:1:"y";i:0;s:1:"m";i:0;s:1:"d";i:7;s:1:"h";i:0;s:1:"i";i:0;s:1:"s";i:0;s:1:"f";d:0;s:7:"weekday";i:0;s:16:"weekday_behavior";i:0;s:17:"first_last_day_of";i:0;s:6:"invert";i:0;s:4:"days";b:0;s:12:"special_type";i:0;s:14:"special_amount";i:0;s:21:"have_weekday_relative";i:0;s:21:"have_special_relative";i:0;}s:11:"recurrences";i:5;s:18:"include_start_date";b:1;}',
10+
]),
711
null,
12+
[],
813
[
9-
'stdClass' => [
10-
'date' => [
11-
'1970-01-01 00:00:00.000000',
12-
],
13-
'timezone_type' => [
14-
1,
15-
],
16-
'timezone' => [
17-
'+00:00',
18-
],
19-
],
14+
$o[0],
15+
$o[1],
16+
$o[2],
17+
$o[3],
18+
$o[4],
2019
],
21-
$o[0],
22-
[
23-
1 => 0,
24-
]
20+
[]
2521
);

Tests/InstantiatorTest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,16 @@ public function testInstantiate()
5353
$expected = [
5454
"\0".__NAMESPACE__."\Bar\0priv" => 123,
5555
"\0".__NAMESPACE__."\Foo\0priv" => 234,
56+
'dyn' => 345,
5657
];
5758

58-
$actual = (array) Instantiator::instantiate(Bar::class, ['priv' => 123], [Foo::class => ['priv' => 234]]);
59+
$actual = (array) Instantiator::instantiate(Bar::class, ['dyn' => 345, 'priv' => 123], [Foo::class => ['priv' => 234]]);
5960
ksort($actual);
6061

6162
$this->assertSame($expected, $actual);
6263

63-
$e = Instantiator::instantiate('Exception', ['foo' => 123, 'trace' => [234]]);
64+
$e = Instantiator::instantiate('Exception', ['trace' => [234]]);
6465

65-
$this->assertSame(123, $e->foo);
6666
$this->assertSame([234], $e->getTrace());
6767
}
6868
}
@@ -72,6 +72,7 @@ class Foo
7272
private $priv;
7373
}
7474

75+
#[\AllowDynamicProperties]
7576
class Bar extends Foo
7677
{
7778
private $priv;

Tests/VarExporterTest.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ public function testExport(string $testName, $value, bool $staticValueExpected =
9595
$dump = "<?php\n\nreturn ".$marshalledValue.";\n";
9696
$dump = str_replace(var_export(__FILE__, true), "\\dirname(__DIR__).\\DIRECTORY_SEPARATOR.'VarExporterTest.php'", $dump);
9797

98-
if (\PHP_VERSION_ID >= 70406 || !\in_array($testName, ['array-object', 'array-iterator', 'array-object-custom', 'spl-object-storage', 'final-array-iterator', 'final-error'], true)) {
98+
if (\PHP_VERSION_ID < 80200 && 'datetime' === $testName) {
99+
$fixtureFile = __DIR__.'/Fixtures/'.$testName.'-legacy.php';
100+
} elseif (\PHP_VERSION_ID >= 70406 || !\in_array($testName, ['array-object', 'array-iterator', 'array-object-custom', 'spl-object-storage', 'final-array-iterator', 'final-error'], true)) {
99101
$fixtureFile = __DIR__.'/Fixtures/'.$testName.'.php';
100102
} elseif (\PHP_VERSION_ID < 70400) {
101103
$fixtureFile = __DIR__.'/Fixtures/'.$testName.'-legacy.php';
@@ -127,9 +129,15 @@ public function provideExport()
127129
yield ['bool', true, true];
128130
yield ['simple-array', [123, ['abc']], true];
129131
yield ['partially-indexed-array', [5 => true, 1 => true, 2 => true, 6 => true], true];
130-
yield ['datetime', \DateTime::createFromFormat('U', 0)];
131-
132-
$value = new \ArrayObject();
132+
yield ['datetime', [
133+
\DateTime::createFromFormat('U', 0),
134+
\DateTimeImmutable::createFromFormat('U', 0),
135+
new \DateTimeZone('Europe/Paris'),
136+
new \DateInterval('P7D'),
137+
new \DatePeriod('R4/2012-07-01T00:00:00Z/P7D'),
138+
]];
139+
140+
$value = \PHP_VERSION_ID >= 70406 ? new ArrayObject() : new \ArrayObject();
133141
$value[0] = 1;
134142
$value->foo = new \ArrayObject();
135143
$value[1] = $value;
@@ -436,3 +444,8 @@ public function unserialize($ser)
436444
throw new \BadMethodCallException();
437445
}
438446
}
447+
448+
#[\AllowDynamicProperties]
449+
class ArrayObject extends \ArrayObject
450+
{
451+
}

0 commit comments

Comments
 (0)