Skip to content

Commit f2a65f4

Browse files
Revert "minor #49684 [DependencyInjection] Use weak references in ContainerBuilder (nicolas-grekas)"
This reverts commit cb39a7f, reversing changes made to 64b4574.
1 parent 268e740 commit f2a65f4

File tree

72 files changed

+80
-420
lines changed

Some content is hidden

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

72 files changed

+80
-420
lines changed

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

+4-5
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,15 @@ public function getProxyFactoryCode(Definition $definition, string $id, string $
6161

6262
return <<<EOF
6363
if (true === \$lazyLoad) {
64-
$instantiation \$container->createProxy('$proxyClass', static function () use (\$containerRef) {
65-
return \\$proxyClass::staticProxyConstructor(static function (&\$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface \$proxy) use (\$containerRef) {
66-
\$container = \$containerRef->get();
64+
$instantiation \$container->createProxy('$proxyClass', static fn () => \\$proxyClass::staticProxyConstructor(
65+
static function (&\$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface \$proxy) use (\$container) {
6766
\$wrappedInstance = $factoryCode;
6867
6968
\$proxy->setProxyInitializer(null);
7069
7170
return true;
72-
});
73-
});
71+
}
72+
));
7473
}
7574
7675

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

+5-8
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,16 @@ class LazyServiceProjectServiceContainer extends Container
55
{%a
66
protected static function getFooService($container, $lazyLoad = true)
77
{
8-
$containerRef = $container->ref;
9-
108
if (true === $lazyLoad) {
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);
9+
return $container->services['foo'] = $container->createProxy('stdClass_%s', static fn () => %S\stdClass_%s(
10+
static function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($container) {
11+
$wrappedInstance = self::getFooService($container, false);
1512

1613
$proxy->setProxyInitializer(null);
1714

1815
return true;
19-
});
20-
});
16+
}
17+
));
2118
}
2219

2320
return new \stdClass();

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

+4-6
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,17 @@
88
public function getFooService($lazyLoad = true)
99
{
1010
$container = $this;
11-
$containerRef = \WeakReference::create($this);
1211

1312
if (true === $lazyLoad) {
14-
return $container->privates['foo'] = $container->createProxy('SunnyInterface_1eff735', static function () use ($containerRef) {
15-
return \SunnyInterface_1eff735::staticProxyConstructor(static function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($containerRef) {
16-
$container = $containerRef->get();
13+
return $container->privates['foo'] = $container->createProxy('SunnyInterface_1eff735', static fn () => \SunnyInterface_1eff735::staticProxyConstructor(
14+
static function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($container) {
1715
$wrappedInstance = $container->getFooService(false);
1816

1917
$proxy->setProxyInitializer(null);
2018

2119
return true;
22-
});
23-
});
20+
}
21+
));
2422
}
2523

2624
return new Symfony\Bridge\ProxyManager\Tests\LazyProxy\PhpDumper\DummyClass();

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

-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ public function testGetProxyFactoryCodeForInterface()
130130
public function getFooService(\$lazyLoad = true)
131131
{
132132
\$container = \$this;
133-
\$containerRef = \\WeakReference::create(\$this);
134133
135134
{$factory} return new {$class}();
136135
}

src/Symfony/Component/DependencyInjection/ContainerBuilder.php

+12-20
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,6 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
141141
*/
142142
private array $removedBindingIds = [];
143143

144-
private \WeakReference $containerRef;
145-
146144
private const INTERNAL_TYPES = [
147145
'int' => true,
148146
'float' => true,
@@ -1064,9 +1062,8 @@ private function createService(Definition $definition, array &$inlineServices, b
10641062
$callable[0] instanceof Reference
10651063
|| $callable[0] instanceof Definition && !isset($inlineServices[spl_object_hash($callable[0])])
10661064
)) {
1067-
$containerRef = $this->containerRef ??= \WeakReference::create($this);
1068-
$initializer = static function () use ($containerRef, $callable, &$inlineServices) {
1069-
return $containerRef->get()->doResolveServices($callable[0], $inlineServices);
1065+
$initializer = function () use ($callable, &$inlineServices) {
1066+
return $this->doResolveServices($callable[0], $inlineServices);
10701067
};
10711068

10721069
$proxy = eval('return '.LazyClosure::getCode('$initializer', $callable, $definition, $this, $id).';');
@@ -1079,14 +1076,13 @@ private function createService(Definition $definition, array &$inlineServices, b
10791076
if (true === $tryProxy && $definition->isLazy() && ['Closure', 'fromCallable'] !== $definition->getFactory()
10801077
&& !$tryProxy = !($proxy = $this->proxyInstantiator ??= new LazyServiceInstantiator()) || $proxy instanceof RealServiceInstantiator
10811078
) {
1082-
$containerRef = $this->containerRef ??= \WeakReference::create($this);
10831079
$proxy = $proxy->instantiateProxy(
10841080
$this,
10851081
(clone $definition)
10861082
->setClass($class)
10871083
->setTags(($definition->hasTag('proxy') ? ['proxy' => $parameterBag->resolveValue($definition->getTag('proxy'))] : []) + $definition->getTags()),
1088-
$id, static function ($proxy = false) use ($containerRef, $definition, &$inlineServices, $id) {
1089-
return $containerRef->get()->createService($definition, $inlineServices, true, $id, $proxy);
1084+
$id, function ($proxy = false) use ($definition, &$inlineServices, $id) {
1085+
return $this->createService($definition, $inlineServices, true, $id, $proxy);
10901086
}
10911087
);
10921088
$this->shareService($definition, $proxy, $id, $inlineServices);
@@ -1214,38 +1210,34 @@ private function doResolveServices(mixed $value, array &$inlineServices = [], bo
12141210
$value[$k] = $this->doResolveServices($v, $inlineServices, $isConstructorArgument);
12151211
}
12161212
} elseif ($value instanceof ServiceClosureArgument) {
1217-
$containerRef = $this->containerRef ??= \WeakReference::create($this);
12181213
$reference = $value->getValues()[0];
1219-
$value = static fn () => $containerRef->get()->resolveServices($reference);
1214+
$value = fn () => $this->resolveServices($reference);
12201215
} elseif ($value instanceof IteratorArgument) {
1221-
$containerRef = $this->containerRef ??= \WeakReference::create($this);
1222-
$value = new RewindableGenerator(static function () use ($containerRef, $value, &$inlineServices) {
1223-
$container = $containerRef->get();
1216+
$value = new RewindableGenerator(function () use ($value, &$inlineServices) {
12241217
foreach ($value->getValues() as $k => $v) {
12251218
foreach (self::getServiceConditionals($v) as $s) {
1226-
if (!$container->has($s)) {
1219+
if (!$this->has($s)) {
12271220
continue 2;
12281221
}
12291222
}
12301223
foreach (self::getInitializedConditionals($v) as $s) {
1231-
if (!$container->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE, $inlineServices)) {
1224+
if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE, $inlineServices)) {
12321225
continue 2;
12331226
}
12341227
}
12351228

1236-
yield $k => $container->doResolveServices($v, $inlineServices);
1229+
yield $k => $this->doResolveServices($v, $inlineServices);
12371230
}
1238-
}, static function () use ($containerRef, $value): int {
1239-
$container = $containerRef->get();
1231+
}, function () use ($value): int {
12401232
$count = 0;
12411233
foreach ($value->getValues() as $v) {
12421234
foreach (self::getServiceConditionals($v) as $s) {
1243-
if (!$container->has($s)) {
1235+
if (!$this->has($s)) {
12441236
continue 2;
12451237
}
12461238
}
12471239
foreach (self::getInitializedConditionals($v) as $s) {
1248-
if (!$container->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) {
1240+
if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) {
12491241
continue 2;
12501242
}
12511243
}

src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

+10-41
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class PhpDumper extends Dumper
6969
private int $variableCount;
7070
private ?\SplObjectStorage $inlinedDefinitions = null;
7171
private ?array $serviceCalls = null;
72-
private array $reservedVariables = ['instance', 'class', 'this', 'container', 'containerRef'];
72+
private array $reservedVariables = ['instance', 'class', 'this', 'container'];
7373
private ExpressionLanguage $expressionLanguage;
7474
private ?string $targetDirRegex = null;
7575
private int $targetDirMaxMatches;
@@ -87,7 +87,6 @@ class PhpDumper extends Dumper
8787
private array $singleUsePrivateIds = [];
8888
private array $preload = [];
8989
private bool $addGetService = false;
90-
private bool $addContainerRef = false;
9190
private array $locatedIds = [];
9291
private string $serviceLocatorTag;
9392
private array $exportedVariables = [];
@@ -247,8 +246,8 @@ public function dump(array $options = []): string|array
247246

248247
if ($this->addGetService) {
249248
$code = preg_replace(
250-
"/(\r?\n\r?\n public function __construct.+?\\{\r?\n) ++([^\r\n]++)/s",
251-
"\n protected \Closure \$getService;$1 \$containerRef = $2\n \$this->getService = static function () use (\$containerRef) { return \$containerRef->get()->getService(...\\func_get_args()); };",
249+
"/\r?\n\r?\n public function __construct.+?\\{\r?\n/s",
250+
"\n protected \Closure \$getService;$0",
252251
$code,
253252
1
254253
);
@@ -862,7 +861,6 @@ private function addService(string $id, Definition $definition): array
862861
} else {
863862
$lazyInitialization = '';
864863
}
865-
$this->addContainerRef = false;
866864

867865
$code = <<<EOF
868866
@@ -875,7 +873,7 @@ private function addService(string $id, Definition $definition): array
875873
876874
*/
877875
protected static function {$methodName}(\$container$lazyInitialization)
878-
{%container_ref%
876+
{
879877
880878
EOF;
881879

@@ -921,9 +919,8 @@ protected static function {$methodName}(\$container$lazyInitialization)
921919
}
922920
}
923921
$lazyLoad = $asGhostObject ? '$proxy' : 'false';
924-
$this->addContainerRef = true;
925922

926-
$factoryCode = $asFile ? sprintf('self::do($containerRef->get(), %s)', $lazyLoad) : sprintf('self::%s($containerRef->get(), %s)', $methodName, $lazyLoad);
923+
$factoryCode = $asFile ? sprintf('self::do($container, %s)', $lazyLoad) : sprintf('self::%s($container, %s)', $methodName, $lazyLoad);
927924
$code .= $this->getProxyDumper()->getProxyFactoryCode($definition, $id, $factoryCode);
928925
}
929926

@@ -945,9 +942,8 @@ protected static function {$methodName}(\$container$lazyInitialization)
945942
if (!$isProxyCandidate && !$definition->isShared()) {
946943
$c = implode("\n", array_map(fn ($line) => $line ? ' '.$line : $line, explode("\n", $c)));
947944
$lazyloadInitialization = $definition->isLazy() ? ', $lazyLoad = true' : '';
948-
$useContainerRef = $this->addContainerRef ? ' use ($containerRef)' : '';
949945

950-
$c = sprintf(" %s = function (\$container%s)%s {\n%s };\n\n return %1\$s(\$container);\n", $factory, $lazyloadInitialization, $useContainerRef, $c);
946+
$c = sprintf(" %s = function (\$container%s) {\n%s };\n\n return %1\$s(\$container);\n", $factory, $lazyloadInitialization, $c);
951947
}
952948

953949
$code .= $c;
@@ -958,8 +954,6 @@ protected static function {$methodName}(\$container$lazyInitialization)
958954
$this->definitionVariables = $this->inlinedDefinitions = null;
959955
$this->referenceVariables = $this->serviceCalls = null;
960956

961-
$code = preg_replace('/%container_ref%/', $this->addContainerRef ? "\n \$containerRef = \$container->ref;\n" : '', $code, 1);
962-
963957
return [$file, $code];
964958
}
965959

@@ -1196,12 +1190,7 @@ private function addNewInstance(Definition $definition, string $return = '', str
11961190
$callable[0] instanceof Reference
11971191
|| ($callable[0] instanceof Definition && !$this->definitionVariables->contains($callable[0]))
11981192
)) {
1199-
if (str_contains($initializer = $this->dumpValue($callable[0]), '$container')) {
1200-
$this->addContainerRef = true;
1201-
$initializer = sprintf('function () use ($containerRef) { $container = $containerRef->get(); return %s; }', $initializer);
1202-
} else {
1203-
$initializer = 'fn () => '.$initializer;
1204-
}
1193+
$initializer = 'fn () => '.$this->dumpValue($callable[0]);
12051194

12061195
return $return.LazyClosure::getCode($initializer, $callable, $definition, $this->container, $id).$tail;
12071196
}
@@ -1268,11 +1257,9 @@ class $class extends $baseClass
12681257
private const DEPRECATED_PARAMETERS = [];
12691258
12701259
protected \$parameters = [];
1271-
protected readonly \WeakReference \$ref;
12721260
12731261
public function __construct()
12741262
{
1275-
\$this->ref = \WeakReference::create(\$this);
12761263
12771264
EOF;
12781265
$code = str_replace(" private const DEPRECATED_PARAMETERS = [];\n\n", $this->addDeprecatedParameters(), $code);
@@ -1853,12 +1840,6 @@ private function dumpValue(mixed $value, bool $interpolate = true): string
18531840
$attribute = sprintf('#[\Closure(%s)] ', $attribute);
18541841
}
18551842

1856-
if (str_contains($code, '$container')) {
1857-
$this->addContainerRef = true;
1858-
1859-
return sprintf("%sfunction () use (\$containerRef)%s {\n \$container = \$containerRef->get();\n\n return %s;\n }", $attribute, $returnedType, $code);
1860-
}
1861-
18621843
return sprintf('%sfn ()%s => %s', $attribute, $returnedType, $code);
18631844
}
18641845

@@ -1867,15 +1848,8 @@ private function dumpValue(mixed $value, bool $interpolate = true): string
18671848
return 'new RewindableGenerator(fn () => new \EmptyIterator(), 0)';
18681849
}
18691850

1870-
$this->addContainerRef = true;
1871-
18721851
$code = [];
1873-
$code[] = 'new RewindableGenerator(function () use ($containerRef) {';
1874-
$code[] = ' $container = $containerRef->get();';
1875-
$code[] = '';
1876-
1877-
$countCode = [];
1878-
$countCode[] = 'function () use ($containerRef) {';
1852+
$code[] = 'new RewindableGenerator(function () use ($container) {';
18791853

18801854
$operands = [0];
18811855
foreach ($values as $k => $v) {
@@ -1888,12 +1862,7 @@ private function dumpValue(mixed $value, bool $interpolate = true): string
18881862
}
18891863
}
18901864

1891-
$countCode[] = ' $container = $containerRef->get();';
1892-
$countCode[] = '';
1893-
$countCode[] = sprintf(' return %s;', implode(' + ', $operands));
1894-
$countCode[] = ' }';
1895-
1896-
$code[] = sprintf(' }, %s)', \count($operands) > 1 ? implode("\n", $countCode) : $operands[0]);
1865+
$code[] = sprintf(' }, %s)', \count($operands) > 1 ? 'fn () => '.implode(' + ', $operands) : $operands[0]);
18971866

18981867
return implode("\n", $code);
18991868
}
@@ -1925,7 +1894,7 @@ private function dumpValue(mixed $value, bool $interpolate = true): string
19251894
}
19261895
$this->addGetService = true;
19271896

1928-
return sprintf('new \%s($container->getService, [%s%s], [%s%s])', ServiceLocator::class, $serviceMap, $serviceMap ? "\n " : '', $serviceTypes, $serviceTypes ? "\n " : '');
1897+
return sprintf('new \%s($container->getService ??= $container->getService(...), [%s%s], [%s%s])', ServiceLocator::class, $serviceMap, $serviceMap ? "\n " : '', $serviceTypes, $serviceTypes ? "\n " : '');
19291898
}
19301899
} finally {
19311900
[$this->definitionVariables, $this->referenceVariables] = $scope;

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/autowire_closure.php

+1-9
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@
1515
class Symfony_DI_PhpDumper_Test_Autowire_Closure extends Container
1616
{
1717
protected $parameters = [];
18-
protected readonly \WeakReference $ref;
1918

2019
public function __construct()
2120
{
22-
$this->ref = \WeakReference::create($this);
2321
$this->services = $this->privates = [];
2422
$this->methodMap = [
2523
'bar' => 'getBarService',
@@ -48,13 +46,7 @@ public function isCompiled(): bool
4846
*/
4947
protected static function getBarService($container)
5048
{
51-
$containerRef = $container->ref;
52-
53-
return $container->services['bar'] = new \Symfony\Component\DependencyInjection\Tests\Dumper\LazyClosureConsumer(#[\Closure(name: 'foo', class: 'Symfony\\Component\\DependencyInjection\\Tests\\Compiler\\Foo')] function () use ($containerRef) {
54-
$container = $containerRef->get();
55-
56-
return ($container->services['foo'] ??= new \Symfony\Component\DependencyInjection\Tests\Compiler\Foo());
57-
}, ($container->services['baz'] ?? self::getBazService($container)), ($container->services['foo'] ??= new \Symfony\Component\DependencyInjection\Tests\Compiler\Foo())->cloneFoo(...), ($container->services['my_callable'] ??= new \Symfony\Component\DependencyInjection\Tests\Compiler\MyCallable())->__invoke(...));
49+
return $container->services['bar'] = new \Symfony\Component\DependencyInjection\Tests\Dumper\LazyClosureConsumer(#[\Closure(name: 'foo', class: 'Symfony\\Component\\DependencyInjection\\Tests\\Compiler\\Foo')] fn () => ($container->services['foo'] ??= new \Symfony\Component\DependencyInjection\Tests\Compiler\Foo()), ($container->services['baz'] ?? self::getBazService($container)), ($container->services['foo'] ??= new \Symfony\Component\DependencyInjection\Tests\Compiler\Foo())->cloneFoo(...), ($container->services['my_callable'] ??= new \Symfony\Component\DependencyInjection\Tests\Compiler\MyCallable())->__invoke(...));
5850
}
5951

6052
/**

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/callable_adapter_consumer.php

-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@
1515
class Symfony_DI_PhpDumper_Test_Callable_Adapter_Consumer extends Container
1616
{
1717
protected $parameters = [];
18-
protected readonly \WeakReference $ref;
1918

2019
public function __construct()
2120
{
22-
$this->ref = \WeakReference::create($this);
2321
$this->services = $this->privates = [];
2422
$this->methodMap = [
2523
'bar' => 'getBarService',

0 commit comments

Comments
 (0)