Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaaf3d4a

Browse files
[VarExporter] Leverage native lazy objects
1 parent273f2ee commitaaf3d4a

16 files changed

+908
-192
lines changed

‎UPGRADE-7.3.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,9 @@ VarDumper
196196

197197
* Deprecate`ResourceCaster::castCurl()`,`ResourceCaster::castGd()` and`ResourceCaster::castOpensslX509()`
198198
* Mark all casters as`@internal`
199+
200+
VarExporter
201+
-----------
202+
203+
* Deprecate`LazyGhostTrait` and`LazyProxyTrait`, use native lazy objects instead
204+
* Deprecate`ProxyHelper::generateLazyGhost()`, use native lazy objects instead

‎src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2036,7 +2036,11 @@ public function testLazyAutowireAttributeWithIntersection()
20362036

20372037
$dumper =newPhpDumper($container);
20382038

2039-
$this->assertStringEqualsFile(self::$fixturesPath.'/php/lazy_autowire_attribute_with_intersection.php',$dumper->dump());
2039+
if (\PHP_VERSION_ID >=80400) {
2040+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/lazy_autowire_attribute_with_intersection.php',$dumper->dump());
2041+
}else {
2042+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/legacy_lazy_autowire_attribute_with_intersection.php',$dumper->dump());
2043+
}
20402044
}
20412045

20422046
publicfunctiontestCallableAdapterConsumer()

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/lazy_autowire_attribute_with_intersection.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,15 @@ protected static function get_Lazy_Foo_QFdMZVKService($container, $lazyLoad = tr
7474

7575
class objectProxy1fd6daaimplements \Symfony\Component\DependencyInjection\Tests\Compiler\AInterface, \Symfony\Component\DependencyInjection\Tests\Compiler\IInterface, \Symfony\Component\VarExporter\LazyObjectInterface
7676
{
77-
use \Symfony\Component\VarExporter\LazyProxyTrait;
77+
use \Symfony\Component\VarExporter\Internal\LazyDecoratorTrait {
78+
doCreateLazyProxyaspublic createLazyProxy;
79+
}
7880

7981
privateconstLAZY_OBJECT_PROPERTY_SCOPES = [];
8082

8183
publicfunctioninitializeLazyObject():\Symfony\Component\DependencyInjection\Tests\Compiler\AInterface&\Symfony\Component\DependencyInjection\Tests\Compiler\IInterface
8284
{
83-
if ($state =$this->lazyObjectState ??null) {
84-
return$state->realInstance ??= ($state->initializer)();
85-
}
86-
87-
return$this;
85+
return$this->lazyObjectState->realInstance;
8886
}
8987
}
9088

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
useSymfony\Component\DependencyInjection\Argument\RewindableGenerator;
4+
useSymfony\Component\DependencyInjection\ContainerInterface;
5+
useSymfony\Component\DependencyInjection\Container;
6+
useSymfony\Component\DependencyInjection\Exception\LogicException;
7+
useSymfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
8+
useSymfony\Component\DependencyInjection\Exception\RuntimeException;
9+
useSymfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
10+
useSymfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
11+
12+
/**
13+
* @internal This class has been auto-generated by the Symfony Dependency Injection Component.
14+
*/
15+
class ProjectServiceContainerextends Container
16+
{
17+
protected$parameters = [];
18+
19+
publicfunction__construct()
20+
{
21+
$this->services =$this->privates = [];
22+
$this->methodMap = [
23+
'foo' =>'getFooService',
24+
];
25+
26+
$this->aliases = [];
27+
}
28+
29+
publicfunctioncompile():void
30+
{
31+
thrownewLogicException('You cannot compile a dumped container that was already compiled.');
32+
}
33+
34+
publicfunctionisCompiled():bool
35+
{
36+
returntrue;
37+
}
38+
39+
protectedfunctioncreateProxy($class,\Closure$factory)
40+
{
41+
return$factory();
42+
}
43+
44+
/**
45+
* Gets the public 'foo' shared autowired service.
46+
*
47+
* @return \Symfony\Component\DependencyInjection\Tests\Compiler\AAndIInterfaceConsumer
48+
*/
49+
protectedstaticfunctiongetFooService($container)
50+
{
51+
$a = ($container->privates['.lazy.foo.qFdMZVK'] ??self::get_Lazy_Foo_QFdMZVKService($container));
52+
53+
if (isset($container->services['foo'])) {
54+
return$container->services['foo'];
55+
}
56+
57+
return$container->services['foo'] =new \Symfony\Component\DependencyInjection\Tests\Compiler\AAndIInterfaceConsumer($a);
58+
}
59+
60+
/**
61+
* Gets the private '.lazy.foo.qFdMZVK' shared service.
62+
*
63+
* @return \object
64+
*/
65+
protectedstaticfunctionget_Lazy_Foo_QFdMZVKService($container,$lazyLoad =true)
66+
{
67+
if (true ===$lazyLoad) {
68+
return$container->privates['.lazy.foo.qFdMZVK'] =$container->createProxy('objectProxy1fd6daa',staticfn () => \objectProxy1fd6daa::createLazyProxy(staticfn () =>self::get_Lazy_Foo_QFdMZVKService($container,false)));
69+
}
70+
71+
return ($container->services['foo'] ??self::getFooService($container));
72+
}
73+
}
74+
75+
class objectProxy1fd6daaimplements \Symfony\Component\DependencyInjection\Tests\Compiler\AInterface, \Symfony\Component\DependencyInjection\Tests\Compiler\IInterface, \Symfony\Component\VarExporter\LazyObjectInterface
76+
{
77+
use \Symfony\Component\VarExporter\LazyProxyTrait;
78+
79+
privateconstLAZY_OBJECT_PROPERTY_SCOPES = [];
80+
81+
publicfunctioninitializeLazyObject():\Symfony\Component\DependencyInjection\Tests\Compiler\AInterface&\Symfony\Component\DependencyInjection\Tests\Compiler\IInterface
82+
{
83+
if ($state =$this->lazyObjectState ??null) {
84+
return$state->realInstance ??= ($state->initializer)();
85+
}
86+
87+
return$this;
88+
}
89+
}
90+
91+
// Help opcache.preload discover always-needed symbols
92+
class_exists(\Symfony\Component\VarExporter\Internal\Hydrator::class);
93+
class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectRegistry::class);
94+
class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class);

‎src/Symfony/Component/VarExporter/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
CHANGELOG
22
=========
33

4+
7.3
5+
---
6+
7+
* Leverage native lazy objects in`ProxyHelper::generateLazyProxy()` on PHP 8.4+
8+
* Deprecate`LazyGhostTrait` and`LazyProxyTrait`, use native lazy objects instead
9+
* Deprecate`ProxyHelper::generateLazyGhost()`, use native lazy objects instead
10+
411
7.2
512
---
613

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\VarExporter\Internal;
13+
14+
useSymfony\Component\Serializer\Attribute\Ignore;
15+
useSymfony\Component\VarExporter\Internal\LazyObjectRegistryasRegistry;
16+
17+
/**
18+
* @internal
19+
*/
20+
trait LazyDecoratorTrait
21+
{
22+
#[Ignore]
23+
privatereadonlyLazyObjectState$lazyObjectState;
24+
25+
/**
26+
* Creates a lazy-loading decorator.
27+
*
28+
* @param \Closure():object $initializer Returns the proxied object
29+
* @param static|null $instance
30+
*/
31+
privatestaticfunctiondoCreateLazyProxy(\Closure$initializer, ?object$instance =null):static
32+
{
33+
$class =$instance ?$instance::class :static::class;
34+
35+
if (self::class ===$class &&\defined($class.'::LAZY_OBJECT_PROPERTY_SCOPES')) {
36+
Hydrator::$propertyScopes[$class] ??=$class::LAZY_OBJECT_PROPERTY_SCOPES;
37+
}
38+
39+
$r = Registry::$classReflectors[$class] ??= ($r =new \ReflectionClass($class))->hasProperty('lazyObjectState') ?$r :thrownew \LogicException('Cannot create a lazy proxy for a non-decorator object.');
40+
$initializer =staticfunction ($ghost)use ($initializer,$class) {
41+
foreach (Registry::$classResetters[$class] ??= Registry::getClassResetters($class)as$reset) {
42+
$reset($ghost, []);
43+
}
44+
45+
$state =$ghost->lazyObjectState ??=newLazyObjectState();
46+
$state->realInstance =$initializer();
47+
$state->initializer =$initializer;
48+
};
49+
50+
if (!$instance) {
51+
return$r->newLazyGhost($initializer);
52+
}
53+
54+
$r->resetAsLazyGhost($instance,$initializer);
55+
56+
return$instance;
57+
}
58+
59+
publicfunction__construct(...$args)
60+
{
61+
self::createLazyProxy(staticfn () =>newparent(...$args),$this);
62+
}
63+
64+
publicfunction__destruct()
65+
{
66+
}
67+
68+
/**
69+
* Returns whether the object is initialized.
70+
*
71+
* @param bool $partial Whether partially initialized objects should be considered as initialized
72+
*/
73+
#[Ignore]
74+
publicfunctionisLazyObjectInitialized(bool$partial =false):bool
75+
{
76+
$r = Registry::$classReflectors[static::class] ??=new \ReflectionClass(static::class);
77+
78+
return !$r->isUninitializedLazyObject($this);
79+
}
80+
81+
/**
82+
* Forces initialization of a lazy object and returns it.
83+
*/
84+
publicfunctioninitializeLazyObject():parent
85+
{
86+
return$this->lazyObjectState->realInstance;
87+
}
88+
89+
/**
90+
* @return bool Returns false when the object cannot be reset, ie when it's not a lazy object
91+
*/
92+
publicfunctionresetLazyObject():bool
93+
{
94+
$r = Registry::$classReflectors[static::class] ??=new \ReflectionClass(static::class);
95+
96+
if ($r->isUninitializedLazyObject($this)) {
97+
returntrue;
98+
}
99+
100+
returnisset($this->lazyObjectState->initializer) &&self::createLazyProxy($this->lazyObjectState->initializer,$this);
101+
}
102+
103+
publicfunction &__get($name):mixed
104+
{
105+
$instance =$this->lazyObjectState->realInstance;
106+
$class =$this::class;
107+
108+
$propertyScopes = Hydrator::$propertyScopes[$class] ??= Hydrator::getPropertyScopes($class);
109+
$notByRef =0;
110+
111+
if ([, , ,$access] =$propertyScopes[$name] ??null) {
112+
$notByRef =$access & Hydrator::PROPERTY_NOT_BY_REF || ($access >>2) & \ReflectionProperty::IS_PRIVATE_SET;
113+
}
114+
115+
if ($notByRef ||2 !== ((Registry::$parentMethods[$class] ??= Registry::getParentMethods($class))['get'] ?:2)) {
116+
$value =$instance->$name;
117+
118+
return$value;
119+
}
120+
121+
try {
122+
return$instance->$name;
123+
}catch (\Error$e) {
124+
if (\Error::class !==$e::class || !str_starts_with($e->getMessage(),'Cannot access uninitialized non-nullable property')) {
125+
throw$e;
126+
}
127+
128+
try {
129+
$instance->$name = [];
130+
131+
return$instance->$name;
132+
}catch (\Error) {
133+
if (preg_match('/^Cannot access uninitialized non-nullable property ([^ ]++) by reference$/',$e->getMessage(),$matches)) {
134+
thrownew \Error('Typed property'.$matches[1].' must not be accessed before initialization',$e->getCode(),$e->getPrevious());
135+
}
136+
137+
throw$e;
138+
}
139+
}
140+
}
141+
142+
publicfunction__set($name,$value):void
143+
{
144+
$this->lazyObjectState->realInstance->$name =$value;
145+
}
146+
147+
publicfunction__isset($name):bool
148+
{
149+
returnisset($this->lazyObjectState->realInstance->$name);
150+
}
151+
152+
publicfunction__unset($name):void
153+
{
154+
unset($this->lazyObjectState->realInstance->$name);
155+
}
156+
157+
publicfunction__serialize():array
158+
{
159+
return [$this->lazyObjectState->realInstance];
160+
}
161+
162+
publicfunction__unserialize($data):void
163+
{
164+
$this->lazyObjectState =newLazyObjectState();
165+
$this->lazyObjectState->realInstance =$data[0];
166+
}
167+
168+
publicfunction__clone():void
169+
{
170+
$this->lazyObjectState =clone$this->lazyObjectState;
171+
}
172+
}

‎src/Symfony/Component/VarExporter/Internal/LazyObjectState.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ class LazyObjectState
3333
publicint$status =self::STATUS_UNINITIALIZED_FULL;
3434

3535
publicobject$realInstance;
36+
publicobject$cloneInstance;
3637

3738
/**
3839
* @param array<string, true> $skippedProperties
3940
*/
4041
publicfunction__construct(
41-
public\Closure$initializer,
42+
public?\Closure$initializer =null,
4243
publicarray$skippedProperties = [],
4344
) {
4445
}
@@ -94,4 +95,17 @@ public function reset($instance): void
9495

9596
$this->status =self::STATUS_UNINITIALIZED_FULL;
9697
}
98+
99+
publicfunction__clone()
100+
{
101+
if (isset($this->cloneInstance)) {
102+
try {
103+
$this->realInstance =$this->cloneInstance;
104+
}finally {
105+
unset($this->cloneInstance);
106+
}
107+
}elseif (isset($this->realInstance)) {
108+
$this->realInstance =clone$this->realInstance;
109+
}
110+
}
97111
}

‎src/Symfony/Component/VarExporter/LazyGhostTrait.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@
1717
useSymfony\Component\VarExporter\Internal\LazyObjectState;
1818
useSymfony\Component\VarExporter\Internal\LazyObjectTrait;
1919

20+
if (\PHP_VERSION_ID >=80400) {
21+
trigger_deprecation('symfony/var-exporter','7.3','The "%s" trait is deprecated, use native lazy objects instead.', LazyGhostTrait::class);
22+
}
23+
24+
/**
25+
* @deprecated since Symfony 7.3, use native lazy objects instead
26+
*/
2027
trait LazyGhostTrait
2128
{
2229
use LazyObjectTrait;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp