Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3b27972

Browse files
-
1 parent 66fdafe commit 3b27972

File tree

6 files changed

+106
-114
lines changed

6 files changed

+106
-114
lines changed

src/Symfony/Bridge/Doctrine/ManagerRegistry.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,30 @@ protected function resetService($name): void
3838
}
3939
$manager = $this->container->get($name);
4040

41+
if (\PHP_VERSION_ID >= 80400) {
42+
$r = new \ReflectionClass($manager);
43+
44+
if ($r->isUninitializedLazyObject($manager)) {
45+
return;
46+
}
47+
48+
$r->resetAsLazyProxy($manager, \Closure::bind(
49+
function () use ($name) {
50+
$name = $this->aliases[$name] ?? $name;
51+
52+
return match (true) {
53+
isset($this->fileMap[$name]) => $this->load($this->fileMap[$name], false),
54+
(new \ReflectionMethod($this, $method = $this->methodMap[$name]))->isStatic() => $this->{$method}($this, false),
55+
default => $this->{$method}(false),
56+
};
57+
},
58+
$this->container,
59+
Container::class
60+
));
61+
62+
return;
63+
}
64+
4165
if ($manager instanceof LazyObjectInterface) {
4266
if (!$manager->resetLazyObject()) {
4367
throw new \LogicException(\sprintf('Resetting a non-lazy manager service is not supported. Declare the "%s" service as lazy.', $name));

src/Symfony/Component/DependencyInjection/LazyProxy/Instantiator/LazyServiceInstantiator.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ public function instantiateProxy(ContainerInterface $container, Definition $defi
2929
throw new InvalidArgumentException(\sprintf('Cannot instantiate lazy proxy for service "%s".', $id));
3030
}
3131

32+
if (\PHP_VERSION_ID >= 80400 && $asGhostObject) {
33+
return (new \ReflectionClass($definition->getClass()))->newLazyGhost(static function () use ($realInstantiator) { $realInstantiator(); });
34+
}
35+
3236
if (!class_exists($proxyClass = $dumper->getProxyClass($definition, $asGhostObject), false)) {
3337
eval($dumper->getProxyCode($definition, $id));
3438
}

src/Symfony/Component/DependencyInjection/LazyProxy/PhpDumper/LazyServiceDumper.php

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,20 @@ public function isProxyCandidate(Definition $definition, ?bool &$asGhostObject =
5656
}
5757
}
5858

59+
$r = new \ReflectionClass($class);
60+
61+
if (\PHP_VERSION_ID < 80400) {
62+
try {
63+
$asGhostObject = (bool) ProxyHelper::generateLazyGhost($r);
64+
} catch (LogicException) {
65+
}
66+
67+
return true;
68+
}
69+
5970
try {
60-
$asGhostObject = (bool) ProxyHelper::generateLazyGhost(new \ReflectionClass($class));
61-
} catch (LogicException) {
71+
$asGhostObject = !$r->isAbstract() && (new \ReflectionClass($class))->newLazyGhost(fn () => null);
72+
} catch (\ReflectionException) {
6273
}
6374

6475
return true;
@@ -85,11 +96,23 @@ public function getProxyFactoryCode(Definition $definition, string $id, string $
8596
EOF;
8697
}
8798

88-
$factoryCode = \sprintf('static fn ($proxy) => %s', $factoryCode);
99+
if (\PHP_VERSION_ID < 80400) {
100+
$factoryCode = \sprintf('static fn ($proxy) => %s', $factoryCode);
101+
102+
return <<<EOF
103+
if (true === \$lazyLoad) {
104+
$instantiation \$container->createProxy('$proxyClass', static fn () => \\$proxyClass::createLazyGhost($factoryCode));
105+
}
106+
107+
108+
EOF;
109+
}
110+
111+
$factoryCode = \sprintf('static function ($proxy) use ($container) { %s; }', $factoryCode);
89112

90113
return <<<EOF
91114
if (true === \$lazyLoad) {
92-
$instantiation \$container->createProxy('$proxyClass', static fn () => \\$proxyClass::createLazyGhost($factoryCode));
115+
$instantiation new \ReflectionClass('$proxyClass')->newLazyGhost($factoryCode);
93116
}
94117
95118
@@ -104,6 +127,10 @@ public function getProxyCode(Definition $definition, ?string $id = null): string
104127
$proxyClass = $this->getProxyClass($definition, $asGhostObject, $class);
105128

106129
if ($asGhostObject) {
130+
if (\PHP_VERSION_ID >= 80400) {
131+
return '';
132+
}
133+
107134
try {
108135
return ($class?->isReadOnly() ? 'readonly ' : '').'class '.$proxyClass.ProxyHelper::generateLazyGhost($class);
109136
} catch (LogicException $e) {
@@ -141,6 +168,10 @@ public function getProxyCode(Definition $definition, ?string $id = null): string
141168

142169
public function getProxyClass(Definition $definition, bool $asGhostObject, ?\ReflectionClass &$class = null): string
143170
{
171+
if (\PHP_VERSION_ID >= 80400 && $asGhostObject) {
172+
return $definition->getClass();
173+
}
174+
144175
$class = 'object' !== $definition->getClass() ? $definition->getClass() : 'stdClass';
145176
$class = new \ReflectionClass($class);
146177

src/Symfony/Component/JsonEncoder/CacheWarmer/LazyGhostCacheWarmer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*
2525
* @internal
2626
*/
27-
final class LazyGhostCacheWarmer extends CacheWarmer
27+
final class LazyGhostCacheWarmer extends CacheWarmer // XXX
2828
{
2929
private Filesystem $fs;
3030

src/Symfony/Component/JsonEncoder/Decode/LazyInstantiator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public function instantiate(string $className, callable $initializer): object
8585
$this->fs->mkdir($this->lazyGhostsDir);
8686
}
8787

88-
file_put_contents($path, \sprintf('<?php class %s%s', $lazyClassName, ProxyHelper::generateLazyGhost($classReflection)));
88+
file_put_contents($path, \sprintf('<?php class %s%s', $lazyClassName, ProxyHelper::generateLazyGhost($classReflection))); // XXX
8989
}
9090

9191
require_once $path;

src/Symfony/Component/VarExporter/ProxyHelper.php

Lines changed: 41 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -59,40 +59,7 @@ public static function generateLazyGhost(\ReflectionClass $class): string
5959
}
6060
}
6161

62-
$hooks = '';
6362
$propertyScopes = Hydrator::$propertyScopes[$class->name] ??= Hydrator::getPropertyScopes($class->name);
64-
foreach ($propertyScopes as $name => $scope) {
65-
if (!isset($scope[4]) || ($p = $scope[3])->isVirtual()) {
66-
continue;
67-
}
68-
69-
if ($p->isFinal()) {
70-
throw new LogicException(sprintf('Cannot generate lazy ghost: property "%s::$%s" is final.', $class->name, $p->name));
71-
}
72-
73-
$type = self::exportType($p);
74-
$hooks .= "\n public {$type} \${$name} {\n";
75-
76-
foreach ($p->getHooks() as $hook => $method) {
77-
if ($method->isFinal()) {
78-
throw new LogicException(sprintf('Cannot generate lazy ghost: hook "%s::%s()" is final.', $class->name, $method->name));
79-
}
80-
81-
if ('get' === $hook) {
82-
$ref = ($method->returnsReference() ? '&' : '');
83-
$hooks .= " {$ref}get { \$this->initializeLazyObject(); return parent::\${$name}::get(); }\n";
84-
} elseif ('set' === $hook) {
85-
$parameters = self::exportParameters($method, true);
86-
$arg = '$'.$method->getParameters()[0]->name;
87-
$hooks .= " set({$parameters}) { \$this->initializeLazyObject(); parent::\${$name}::set({$arg}); }\n";
88-
} else {
89-
throw new LogicException(sprintf('Cannot generate lazy ghost: hook "%s::%s()" is not supported.', $class->name, $method->name));
90-
}
91-
}
92-
93-
$hooks .= " }\n";
94-
}
95-
9663
$propertyScopes = self::exportPropertyScopes($class->name, $propertyScopes);
9764

9865
return <<<EOPHP
@@ -101,7 +68,7 @@ public static function generateLazyGhost(\ReflectionClass $class): string
10168
use \Symfony\Component\VarExporter\LazyGhostTrait;
10269
10370
private const LAZY_OBJECT_PROPERTY_SCOPES = {$propertyScopes};
104-
{$hooks}}
71+
}
10572
10673
// Help opcache.preload discover always-needed symbols
10774
class_exists(\Symfony\Component\VarExporter\Internal\Hydrator::class);
@@ -132,20 +99,9 @@ public static function generateLazyProxy(?\ReflectionClass $class, array $interf
13299

133100
$propertyScopes = $class ? Hydrator::$propertyScopes[$class->name] ??= Hydrator::getPropertyScopes($class->name) : [];
134101
$abstractProperties = [];
135-
$hookedProperties = [];
136102
if (\PHP_VERSION_ID >= 80400 && $class) {
137103
foreach ($propertyScopes as $name => $scope) {
138-
if (!isset($scope[4]) || ($p = $scope[3])->isVirtual()) {
139-
$abstractProperties[$name] = isset($scope[4]) && $p->isAbstract() ? $p : false;
140-
continue;
141-
}
142-
143-
if ($p->isFinal()) {
144-
throw new LogicException(\sprintf('Cannot generate lazy proxy: property "%s::$%s" is final.', $class->name, $p->name));
145-
}
146-
147-
$abstractProperties[$name] = false;
148-
$hookedProperties[$name] = [$p, $p->getHooks()];
104+
$abstractProperties[$name] = isset($scope[4]) && ($p = $scope[3])->isAbstract() ? $p : false;
149105
}
150106
}
151107

@@ -156,12 +112,12 @@ public static function generateLazyProxy(?\ReflectionClass $class, array $interf
156112
}
157113
$methodReflectors[] = $interface->getMethods();
158114

159-
if (\PHP_VERSION_ID >= 80400) {
160-
foreach ($interface->getProperties() as $p) {
161-
$abstractProperties[$p->name] ??= $p;
162-
$hookedProperties[$p->name] ??= [$p, []];
163-
$hookedProperties[$p->name][1] += $p->getHooks();
164-
}
115+
if (\PHP_VERSION_ID < 80400) {
116+
continue;
117+
}
118+
119+
foreach ($interface->getProperties() as $p) {
120+
$abstractProperties[$p->name] ??= $p;
165121
}
166122
}
167123

@@ -173,49 +129,6 @@ public static function generateLazyProxy(?\ReflectionClass $class, array $interf
173129
unset($propertyScopes[$name][4]);
174130
}
175131

176-
foreach ($hookedProperties as $name => [$p, $methods]) {
177-
$type = self::exportType($p);
178-
$hooks .= "\n public {$type} \${$p->name} {\n";
179-
180-
foreach ($methods as $hook => $method) {
181-
if ($method->isFinal()) {
182-
throw new LogicException(sprintf('Cannot generate lazy proxy: hook "%s::%s()" is final.', $class->name, $method->name));
183-
}
184-
185-
if ('get' === $hook) {
186-
$ref = ($method->returnsReference() ? '&' : '');
187-
$hooks .= <<<EOPHP
188-
{$ref}get {
189-
if (isset(\$this->lazyObjectState)) {
190-
return (\$this->lazyObjectState->realInstance ??= (\$this->lazyObjectState->initializer)())->{$p->name};
191-
}
192-
193-
return parent::\${$p->name}::get();
194-
}
195-
196-
EOPHP;
197-
} elseif ('set' === $hook) {
198-
$parameters = self::exportParameters($method, true);
199-
$arg = '$'.$method->getParameters()[0]->name;
200-
$hooks .= <<<EOPHP
201-
set({$parameters}) {
202-
if (isset(\$this->lazyObjectState)) {
203-
\$this->lazyObjectState->realInstance ??= (\$this->lazyObjectState->initializer)();
204-
\$this->lazyObjectState->realInstance->{$p->name} = {$arg};
205-
}
206-
207-
parent::\${$p->name}::set({$arg});
208-
}
209-
210-
EOPHP;
211-
} else {
212-
throw new LogicException(sprintf('Cannot generate lazy proxy: hook "%s::%s()" is not supported.', $class->name, $method->name));
213-
}
214-
}
215-
216-
$hooks .= " }\n";
217-
}
218-
219132
$extendsInternalClass = false;
220133
if ($parent = $class) {
221134
do {
@@ -261,13 +174,23 @@ public static function generateLazyProxy(?\ReflectionClass $class, array $interf
261174
if ($method->isStatic()) {
262175
$body = " $parentCall;";
263176
} elseif (str_ends_with($signature, '): never') || str_ends_with($signature, '): void')) {
264-
$body = <<<EOPHP
265-
if (isset(\$this->lazyObjectState)) {
266-
(\$this->lazyObjectState->realInstance ??= (\$this->lazyObjectState->initializer)())->{$method->name}({$args});
267-
} else {
268-
{$parentCall};
269-
}
270-
EOPHP;
177+
if (PHP_VERSION_ID < 80400) {
178+
$body = <<<EOPHP
179+
if (isset(\$this->lazyObjectState)) {
180+
(\$this->lazyObjectState->realInstance ??= (\$this->lazyObjectState->initializer)())->{$method->name}({$args});
181+
} else {
182+
{$parentCall};
183+
}
184+
EOPHP;
185+
} else {
186+
$body = <<<EOPHP
187+
if (\$this !== \${''} = (\Symfony\Component\VarExporter\Internal\LazyObjectRegistry::\$classReflectors[static::class] ??= new \ReflectionClass(static::class))->initializeLazyObject(\$this)) {
188+
\${''}->{$method->name}({$args});
189+
} else {
190+
{$parentCall};
191+
}
192+
EOPHP;
193+
}
271194
} else {
272195
if (!$methodsHaveToBeProxied && !$method->isAbstract()) {
273196
// Skip proxying methods that might return $this
@@ -283,13 +206,23 @@ public static function generateLazyProxy(?\ReflectionClass $class, array $interf
283206
}
284207
}
285208

286-
$body = <<<EOPHP
287-
if (isset(\$this->lazyObjectState)) {
288-
return (\$this->lazyObjectState->realInstance ??= (\$this->lazyObjectState->initializer)())->{$method->name}({$args});
289-
}
209+
if (PHP_VERSION_ID < 80400) {
210+
$body = <<<EOPHP
211+
if (isset(\$this->lazyObjectState)) {
212+
return (\$this->lazyObjectState->realInstance ??= (\$this->lazyObjectState->initializer)())->{$method->name}({$args});
213+
}
290214
291-
return {$parentCall};
292-
EOPHP;
215+
return {$parentCall};
216+
EOPHP;
217+
} else {
218+
$body = <<<EOPHP
219+
if (\$this !== \${''} = (\Symfony\Component\VarExporter\Internal\LazyObjectRegistry::\$classReflectors[static::class] ??= new \ReflectionClass(static::class))->initializeLazyObject(\$this)) {
220+
return \${''}->{$method->name}({$args});
221+
}
222+
223+
return {$parentCall};
224+
EOPHP;
225+
}
293226
}
294227
$methods[$lcName] = " {$signature}\n {\n{$body}\n }";
295228
}

0 commit comments

Comments
 (0)