8000 [VarExporter] generate __doUnserialize() method in ProxyHelper::gener… · symfony/symfony@764f35b · GitHub
[go: up one dir, main page]

Skip to content

Commit 764f35b

Browse files
committed
[VarExporter] generate __doUnserialize() method in ProxyHelper::generateLazyProxy()
1 parent e3b80f3 commit 764f35b

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

src/Symfony/Component/VarExporter/ProxyHelper.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,36 @@ public static function generateLazyProxy(?\ReflectionClass $class, array $interf
197197
$body = $methods ? "\n".implode("\n\n", $methods)."\n" : '';
198198
$propertyScopes = $class ? self::exportPropertyScopes($class->name) : '[]';
199199

200+
if (
201+
$class?->hasMethod('__unserialize')
202+
&& null !== ($unserializeParameter = $class->getMethod('__unserialize')->getParameters()[0] ?? null)
203+
&& null === $unserializeParameter->getType()
204+
) {
205+
// fix type problem when $class declares a `__unserialize()` method without typehint.
206+
$lazyProxyTraitStatement = <<<EOPHP
207+
use \Symfony\Component\VarExporter\LazyProxyTrait {
208+
__unserialize as private __doUnserialize;
209+
}
210+
EOPHP;
211+
212+
$body .= <<<EOPHP
213+
214+
public function __unserialize(\$data): void
215+
{
216+
\$this->__doUnserialize(\$data);
217+
}
218+
219+
EOPHP;
220+
} else {
221+
$lazyProxyTraitStatement = <<<EOPHP
222+
use \Symfony\Component\VarExporter\LazyProxyTrait;
223+
EOPHP;
224+
}
225+
200226
return <<<EOPHP
201227
{$parent} implements \\{$interfaces}
202228
{
203-
use \Symfony\Component\VarExporter\LazyProxyTrait;
229+
{$lazyProxyTraitStatement}
204230
205231
private const LAZY_OBJECT_PROPERTY_SCOPES = {$propertyScopes};
206232
{$body}}

src/Symfony/Component/VarExporter/Tests/ProxyHelperTest.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,50 @@ class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class);
160160
$this->assertSame($expected, ProxyHelper::generateLazyProxy(null, [new \ReflectionClass(TestForProxyHelperInterface1::class), new \ReflectionClass(TestForProxyHelperInterface2::class)]));
161161
}
162162

163+
/**
164+
* @dataProvider classWithUnserializeMagicMethodProvider
165+
*/
166+
public function testGenerateLazyProxyForClassWithUnserializeMagicMethod(object $obj, string $expected)
167+
{
168+
$this->assertStringContainsString($expected, ProxyHelper::generateLazyProxy(new \ReflectionClass($obj::class)));
169+
}
170+
171+
public static function classWithUnserializeMagicMethodProvider(): iterable
172+
{
173+
yield 'not type hinted __unserialize method' => [new class() {
174+
public function __unserialize($array)
175+
{
176+
}
177+
}, <<<'EOPHP'
178+
implements \Symfony\Component\VarExporter\LazyObjectInterface
179+
{
180+
use \Symfony\Component\VarExporter\LazyProxyTrait {
181+
__unserialize as private __doUnserialize;
182+
}
183+
184+
private const LAZY_OBJECT_PROPERTY_SCOPES = [];
185+
186+
public function __unserialize($data): void
187+
{
188+
$this->__doUnserialize($data);
189+
}
190+
}
191+
EOPHP];
192+
193+
yield 'type hinted __unserialize method' => [new class() {
194+
public function __unserialize(array $array)
195+
{
196+
}
197+
}, <<<'EOPHP'
198+
implements \Symfony\Component\VarExporter\LazyObjectInterface
199+
{
200+
use \Symfony\Component\VarExporter\LazyProxyTrait;
201+
202+
private const LAZY_OBJECT_PROPERTY_SCOPES = [];
203+
}
204+
EOPHP];
205+
}
206+
163207
public function testAttributes()
164208
{
165209
$expected = <<<'EOPHP'
@@ -182,6 +226,7 @@ public function foo(#[\SensitiveParameter, AnotherAttribute] $a): int
182226
{
183227
}
184228
});
229+
185230
$this->assertStringContainsString($expected, ProxyHelper::generateLazyProxy($class));
186231
}
187232

0 commit comments

Comments
 (0)
0