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

Skip to content

Commit 2e6a1ab

Browse files
committed
Fix container injection with TypedReference
1 parent a0ac3b0 commit 2e6a1ab

File tree

3 files changed

+189
-3
lines changed

3 files changed

+189
-3
lines changed

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@ protected function {$methodName}($lazyInitialization)
904904

905905
$factoryCode = $asFile ? 'self::do($container, false)' : sprintf('$this->%s(false)', $methodName);
906906
$factoryCode = $this->getProxyDumper()->getProxyFactoryCode($definition, $id, $factoryCode);
907-
$code .= $asFile ? preg_replace('/function \(([^)]*+)\) {/', 'function (\1) use ($container) {', $factoryCode) : $factoryCode;
907+
$code .= $asFile ? preg_replace('/function \(([^)]*+)\)( {|:)/', 'function (\1) use ($container)\2', $factoryCode) : $factoryCode;
908908
}
909909

910910
$c = $this->addServiceInclude($id, $definition);
@@ -934,8 +934,7 @@ protected function {$methodName}($lazyInitialization)
934934

935935
if ($asFile) {
936936
$code = str_replace('$this', '$container', $code);
937-
$code = str_replace('function () {', 'function () use ($container) {', $code);
938-
$code = str_replace('function ($lazyLoad = true) {', 'function ($lazyLoad = true) use ($container) {', $code);
937+
$code = preg_replace('/function \(([^)]*+)\)( {|:)/', 'function (\1) use ($container)\2', $code);
939938
}
940939

941940
$code .= " }\n";

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,26 @@ public function testDumpAsFiles()
244244
$this->assertStringMatchesFormatFile(self::$fixturesPath.'/php/services9_as_files.txt', $dump);
245245
}
246246

247+
public function testDumpAsFilesWithTypedReference()
248+
{
249+
$container = include self::$fixturesPath.'/containers/container10.php';
250+
$container->getDefinition('foo')->addTag('hot');
251+
$container->register('bar', 'stdClass');
252+
$container->register('closure', 'stdClass')
253+
->setProperty('closures', [
254+
new ServiceClosureArgument(new TypedReference('foo', \stdClass::class, $container::IGNORE_ON_UNINITIALIZED_REFERENCE)),
255+
])
256+
->setPublic(true);
257+
$container->compile();
258+
$dumper = new PhpDumper($container);
259+
$dump = print_r($dumper->dump(['as_files' => true, 'file' => __DIR__, 'hot_path_tag' => 'hot', 'inline_factories_parameter' => false, 'inline_class_loader_parameter' => false]), true);
260+
if ('\\' === \DIRECTORY_SEPARATOR) {
261+
$dump = str_replace("'.\\DIRECTORY_SEPARATOR.'", '/', $dump);
262+
}
263+
264+
$this->assertStringMatchesFormatFile(self::$fixturesPath.'/php/services10_as_files.txt', $dump);
265+
}
266+
247267
public function testDumpAsFilesWithFactoriesInlined()
248268
{
249269
$container = include self::$fixturesPath.'/containers/container9.php';
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
Array
2+
(
3+
[Container%s/removed-ids.php] => <?php
4+
5+
namespace Container%s;
6+
7+
return [
8+
'Psr\\Container\\ContainerInterface' => true,
9+
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
10+
'bar' => true,
11+
];
12+
13+
[Container%s/getClosureService.php] => <?php
14+
15+
namespace Container%s;
16+
17+
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
18+
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
19+
20+
/**
21+
* @internal This class has been auto-generated by the Symfony Dependency Injection Component.
22+
*/
23+
class getClosureService extends ProjectServiceContainer
24+
{
25+
/**
26+
* Gets the public 'closure' shared service.
27+
*
28+
* @return \stdClass
29+
*/
30+
public static function do($container, $lazyLoad = true)
31+
{
32+
$container->services['closure'] = $instance = new \stdClass();
33+
34+
$instance->closures = [0 => function () use ($container): ?\stdClass {
35+
return ($container->services['foo'] ?? null);
36+
}];
37+
38+
return $instance;
39+
}
40+
}
41+
42+
[Container%s/ProjectServiceContainer.php] => <?php
43+
44+
namespace Container%s;
45+
46+
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
47+
use Symfony\Component\DependencyInjection\ContainerInterface;
48+
use Symfony\Component\DependencyInjection\Container;
49+
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
50+
use Symfony\Component\DependencyInjection\Exception\LogicException;
51+
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
52+
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
53+
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
54+
55+
/**
56+
* @internal This class has been auto-generated by the Symfony Dependency Injection Component.
57+
*/
58+
class ProjectServiceContainer extends Container
59+
{
60+
protected $containerDir;
61+
protected $targetDir;
62+
protected $parameters = [];
63+
private $buildParameters;
64+
65+
public function __construct(array $buildParameters = [], $containerDir = __DIR__)
66+
{
67+
$this->buildParameters = $buildParameters;
68+
$this->containerDir = $containerDir;
69+
$this->targetDir = \dirname($containerDir);
70+
$this->services = $this->privates = [];
71+
$this->methodMap = [
72+
'foo' => 'getFooService',
73+
];
74+
$this->fileMap = [
75+
'closure' => 'getClosureService',
76+
];
77+
78+
$this->aliases = [];
79+
}
80+
81+
public function compile(): void
82+
{
83+
throw new LogicException('You cannot compile a dumped container that was already compiled.');
84+
}
85+
86+
public function isCompiled(): bool
87+
{
88+
return true;
89+
}
90+
91+
public function getRemovedIds(): array
92+
{
93+
return require $this->containerDir.\DIRECTORY_SEPARATOR.'removed-ids.php';
94+
}
95+
96+
protected function load($file, $lazyLoad = true)
97+
{
98+
if (class_exists($class = __NAMESPACE__.'\\'.$file, false)) {
99+
return $class::do($this, $lazyLoad);
100+
}
101+
102+
if ('.' === $file[-4]) {
103+
$class = substr($class, 0, -4);
104+
} else {
105+
$file .= '.php';
106+
}
107+
108+
$service = require $this->containerDir.\DIRECTORY_SEPARATOR.$file;
109+
110+
return class_exists($class, false) ? $class::do($this, $lazyLoad) : $service;
111+
}
112+
113+
/**
114+
* Gets the public 'foo' shared service.
115+
*
116+
* @return \FooClass
117+
*/
118+
protected function getFooService()
119+
{
120+
return $this->services['foo'] = new \FooClass(new \stdClass());
121+
}
122+
}
123+
124+
[ProjectServiceContainer.preload.php] => <?php
125+
126+
// This file has been auto-generated by the Symfony Dependency Injection Component
127+
// You can reference it in the "opcache.preload" php.ini setting on PHP >= 7.4 when preloading is desired
128+
129+
use Symfony\Component\DependencyInjection\Dumper\Preloader;
130+
131+
if (in_array(PHP_SAPI, ['cli', 'phpdbg'], true)) {
132+
return;
133+
}
134+
135+
require dirname(__DIR__, 5).'/vendor/autoload.php';
136+
require __DIR__.'/Container%s/ProjectServiceContainer.php';
137+
require __DIR__.'/Container%s/getClosureService.php';
138+
139+
$classes = [];
140+
$classes[] = 'FooClass';
141+
$classes[] = 'Symfony\Component\DependencyInjection\ContainerInterface';
142+
143+
Preloader::preload($classes);
144+
145+
[ProjectServiceContainer.php] => <?php
146+
147+
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
148+
149+
if (\class_exists(\Container%s\ProjectServiceContainer::class, false)) {
150+
// no-op
151+
} elseif (!include __DIR__.'/Container%s/ProjectServiceContainer.php') {
152+
touch(__DIR__.'/Container%s.legacy');
153+
154+
return;
155+
}
156+
157+
if (!\class_exists(ProjectServiceContainer::class, false)) {
158+
\class_alias(\Container%s\ProjectServiceContainer::class, ProjectServiceContainer::class, false);
159+
}
160+
161+
return new \Container%s\ProjectServiceContainer([
162+
'container.build_hash' => '%s',
163+
'container.build_id' => '%s',
164+
'container.build_time' => %d,
165+
], __DIR__.\DIRECTORY_SEPARATOR.'Container%s');
166+
167+
)

0 commit comments

Comments
 (0)