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

Commit11a279f

Browse files
[DependencyInjection] Use WeakReference to break circular references in the container
1 parent6c8f6b3 commit11a279f

File tree

66 files changed

+1097
-840
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+1097
-840
lines changed

‎src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,17 @@ public function getProxyFactoryCode(Definition $definition, string $id, string $
4949
$instantiation ='return';
5050

5151
if ($definition->isShared()) {
52-
$instantiation .=sprintf(' $this->%s[%s] =',$definition->isPublic() && !$definition->isPrivate() ?'services' :'privates',var_export($id,true));
52+
$instantiation .=sprintf(' $container->%s[%s] =',$definition->isPublic() && !$definition->isPrivate() ?'services' :'privates',var_export($id,true));
5353
}
5454

5555
$proxifiedClass =new \ReflectionClass($this->proxyGenerator->getProxifiedClass($definition));
5656
$proxyClass =$this->getProxyClassName($proxifiedClass->name);
5757

5858
return<<<EOF
5959
if (true ===\$lazyLoad) {
60-
$instantiation\$this->createProxy('$proxyClass', function () {
61-
return \\$proxyClass::staticProxyConstructor(function (&\$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface\$proxy) {
60+
$instantiation\$container->createProxy('$proxyClass', static function () use (\$containerRef) {
61+
return \\$proxyClass::staticProxyConstructor(static function (&\$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface\$proxy) use (\$containerRef) {
62+
\$container =\$containerRef->get();
6263
\$wrappedInstance =$factoryCode;
6364
6465
\$proxy->setProxyInitializer(null);

‎src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/php/lazy_service_structure.txt‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
use %a
44
class LazyServiceProjectServiceContainer extends Container
55
{%a
6-
protected function getFooService($lazyLoad = true)
6+
protectedstaticfunction getFooService($container,$lazyLoad = true)
77
{
8+
$containerRef = $container->ref;
9+
810
if (true === $lazyLoad) {
9-
return $this->services['foo'] = $this->createProxy('stdClass_%s', function () {
10-
return %S\stdClass_%s(function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) {
11-
$wrappedInstance = $this->getFooService(false);
11+
return $container->services['foo'] = $container->createProxy('stdClass_%s', static function () use ($containerRef) {
12+
return %S\stdClass_%s(static function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($containerRef) {
13+
$container = $containerRef->get();
14+
$wrappedInstance = self::getFooService($containerRef->get(), false);
1215

1316
$proxy->setProxyInitializer(null);
1417

‎src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-factory.php‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@
77

88
publicfunctiongetFooService($lazyLoad =true)
99
{
10+
$container =$this;
11+
$containerRef = \WeakReference::create($this);
12+
1013
if (true ===$lazyLoad) {
11-
return$this->privates['foo'] =$this->createProxy('SunnyInterface_1eff735',function () {
12-
return \SunnyInterface_1eff735::staticProxyConstructor(function (&$wrappedInstance,\ProxyManager\Proxy\LazyLoadingInterface$proxy) {
13-
$wrappedInstance =$this->getFooService(false);
14+
return$container->privates['foo'] =$container->createProxy('SunnyInterface_1eff735',staticfunction ()use ($containerRef) {
15+
return \SunnyInterface_1eff735::staticProxyConstructor(staticfunction (&$wrappedInstance,\ProxyManager\Proxy\LazyLoadingInterface$proxy)use ($containerRef) {
16+
$container =$containerRef->get();
17+
$wrappedInstance =$container->getFooService(false);
1418

1519
$proxy->setProxyInitializer(null);
1620

‎src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,10 @@ public function testGetProxyFactoryCode()
7070

7171
$definition->setLazy(true);
7272

73-
$code =$this->dumper->getProxyFactoryCode($definition,'foo','$this->getFoo2Service(false)');
73+
$code =$this->dumper->getProxyFactoryCode($definition,'foo','$container->getFoo2Service(false)');
7474

7575
$this->assertStringMatchesFormat(
76-
'%A$wrappedInstance = $this->getFoo2Service(false);%w$proxy->setProxyInitializer(null);%A',
76+
'%A$wrappedInstance = $container->getFoo2Service(false);%w$proxy->setProxyInitializer(null);%A',
7777
$code
7878
);
7979
}
@@ -85,9 +85,9 @@ public function testCorrectAssigning(Definition $definition, $access)
8585
{
8686
$definition->setLazy(true);
8787

88-
$code =$this->dumper->getProxyFactoryCode($definition,'foo','$this->getFoo2Service(false)');
88+
$code =$this->dumper->getProxyFactoryCode($definition,'foo','$container->getFoo2Service(false)');
8989

90-
$this->assertStringMatchesFormat('%A$this->'.$access.'[\'foo\'] = %A',$code);
90+
$this->assertStringMatchesFormat('%A$container->'.$access.'[\'foo\'] = %A',$code);
9191
}
9292

9393
publicfunctiongetPrivatePublicDefinitions()
@@ -116,7 +116,7 @@ public function testGetProxyFactoryCodeForInterface()
116116
$definition->addTag('proxy', ['interface' => SunnyInterface::class]);
117117

118118
$implem ="<?php\n\n".$this->dumper->getProxyCode($definition);
119-
$factory =$this->dumper->getProxyFactoryCode($definition,'foo','$this->getFooService(false)');
119+
$factory =$this->dumper->getProxyFactoryCode($definition,'foo','$container->getFooService(false)');
120120
$factory =<<<EOPHP
121121
<?php
122122
@@ -127,6 +127,9 @@ public function testGetProxyFactoryCodeForInterface()
127127
128128
public function getFooService(\$lazyLoad = true)
129129
{
130+
\$container =\$this;
131+
\$containerRef = \\WeakReference::create(\$this);
132+
130133
{$factory} return new{$class}();
131134
}
132135

‎src/Symfony/Bridge/ProxyManager/composer.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"require": {
1919
"php":">=8.1",
2020
"friendsofphp/proxy-manager-lts":"^1.0.2",
21-
"symfony/dependency-injection":"^6.2"
21+
"symfony/dependency-injection":"^6.3"
2222
},
2323
"require-dev": {
2424
"symfony/config":"^6.1"

‎src/Symfony/Component/DependencyInjection/Container.php‎

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ class Container implements ContainerInterface, ResetInterface
6363
privatebool$compiled =false;
6464
private\Closure$getEnv;
6565

66+
privatestatic$make;
67+
6668
publicfunction__construct(ParameterBagInterface$parameterBag =null)
6769
{
6870
$this->parameterBag =$parameterBag ??newEnvPlaceholderParameterBag();
@@ -135,7 +137,7 @@ public function set(string $id, ?object $service)
135137
if (isset($this->privates['service_container']) &&$this->privates['service_container']instanceof \Closure) {
136138
$initialize =$this->privates['service_container'];
137139
unset($this->privates['service_container']);
138-
$initialize();
140+
$initialize($this);
139141
}
140142

141143
if ('service_container' ===$id) {
@@ -195,49 +197,49 @@ public function get(string $id, int $invalidBehavior = self::EXCEPTION_ON_INVALI
195197
{
196198
return$this->services[$id]
197199
??$this->services[$id =$this->aliases[$id] ??$id]
198-
?? ('service_container' ===$id ?$this : ($this->factories[$id] ??$this->make(...))($id,$invalidBehavior));
200+
?? ('service_container' ===$id ?$this : ($this->factories[$id] ??self::$make ??=self::make(...))($this,$id,$invalidBehavior));
199201
}
200202

201203
/**
202204
* Creates a service.
203205
*
204206
* As a separate method to allow "get()" to use the really fast `??` operator.
205207
*/
206-
privatefunctionmake(string$id,int$invalidBehavior)
208+
privatestaticfunctionmake($container,string$id,int$invalidBehavior)
207209
{
208-
if (isset($this->loading[$id])) {
209-
thrownewServiceCircularReferenceException($id,array_merge(array_keys($this->loading), [$id]));
210+
if (isset($container->loading[$id])) {
211+
thrownewServiceCircularReferenceException($id,array_merge(array_keys($container->loading), [$id]));
210212
}
211213

212-
$this->loading[$id] =true;
214+
$container->loading[$id] =true;
213215

214216
try {
215-
if (isset($this->fileMap[$id])) {
216-
return/* self::IGNORE_ON_UNINITIALIZED_REFERENCE */4 ===$invalidBehavior ?null :$this->load($this->fileMap[$id]);
217-
}elseif (isset($this->methodMap[$id])) {
218-
return/* self::IGNORE_ON_UNINITIALIZED_REFERENCE */4 ===$invalidBehavior ?null :$this->{$this->methodMap[$id]}();
217+
if (isset($container->fileMap[$id])) {
218+
return/* self::IGNORE_ON_UNINITIALIZED_REFERENCE */4 ===$invalidBehavior ?null :$container->load($container->fileMap[$id]);
219+
}elseif (isset($container->methodMap[$id])) {
220+
return/* self::IGNORE_ON_UNINITIALIZED_REFERENCE */4 ===$invalidBehavior ?null :$container->{$container->methodMap[$id]}($container);
219221
}
220222
}catch (\Exception$e) {
221-
unset($this->services[$id]);
223+
unset($container->services[$id]);
222224

223225
throw$e;
224226
}finally {
225-
unset($this->loading[$id]);
227+
unset($container->loading[$id]);
226228
}
227229

228230
if (self::EXCEPTION_ON_INVALID_REFERENCE ===$invalidBehavior) {
229231
if (!$id) {
230232
thrownewServiceNotFoundException($id);
231233
}
232-
if (isset($this->syntheticIds[$id])) {
234+
if (isset($container->syntheticIds[$id])) {
233235
thrownewServiceNotFoundException($id,null,null, [],sprintf('The "%s" service is synthetic, it needs to be set at boot time before it can be used.',$id));
234236
}
235-
if (isset($this->getRemovedIds()[$id])) {
237+
if (isset($container->getRemovedIds()[$id])) {
236238
thrownewServiceNotFoundException($id,null,null, [],sprintf('The "%s" service or alias has been removed or inlined when the container was compiled. You should either make it public, or stop using the container directly and use dependency injection instead.',$id));
237239
}
238240

239241
$alternatives = [];
240-
foreach ($this->getServiceIds()as$knownId) {
242+
foreach ($container->getServiceIds()as$knownId) {
241243
if ('' ===$knownId ||'.' ===$knownId[0]) {
242244
continue;
243245
}
@@ -378,13 +380,13 @@ final protected function getService(string|false $registry, string $id, ?string
378380
returnfalse !==$registry ?$this->{$registry}[$id] ??null :null;
379381
}
380382
if (false !==$registry) {
381-
return$this->{$registry}[$id] ??=$load ?$this->load($method) :$this->{$method}();
383+
return$this->{$registry}[$id] ??=$load ?$this->load($method) :$this->{$method}($this);
382384
}
383385
if (!$load) {
384-
return$this->{$method}();
386+
return$this->{$method}($this);
385387
}
386388

387-
return ($factory =$this->factories[$id] ??$this->factories['service_container'][$id] ??null) ?$factory() :$this->load($method);
389+
return ($factory =$this->factories[$id] ??$this->factories['service_container'][$id] ??null) ?$factory($this) :$this->load($method);
388390
}
389391

390392
privatefunction__clone()

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp