Skip to content

Commit adf1819

Browse files
[DI] Fix false-positive circular exception
1 parent b9fb27c commit adf1819

File tree

6 files changed

+72
-1
lines changed

6 files changed

+72
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ private function addServiceInlinedDefinitions($id, Definition $definition, \SplO
478478
// $b = new ServiceB();
479479
// $a = new ServiceA(ServiceB $b);
480480
// $b->setServiceA(ServiceA $a);
481-
if ($this->hasReference($id, array($def->getArguments(), $def->getFactory()))) {
481+
if (isset($inlinedDefinition[$definition]) && $this->hasReference($id, array($def->getArguments(), $def->getFactory()))) {
482482
throw new ServiceCircularReferenceException($id, array($id));
483483
}
484484

src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,9 @@ public function testAlmostCircular($visibility)
12631263
$this->assertSame($foo2, $foo2->bar->foobar->foo);
12641264

12651265
$this->assertSame(array(), (array) $container->get('foobar4'));
1266+
1267+
$foo5 = $container->get('foo5');
1268+
$this->assertSame($foo5, $foo5->bar->foo);
12661269
}
12671270

12681271
public function provideAlmostCircular()

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,9 @@ public function testAlmostCircular($visibility)
782782
$this->assertSame($foo2, $foo2->bar->foobar->foo);
783783

784784
$this->assertSame(array(), (array) $container->get('foobar4'));
785+
786+
$foo5 = $container->get('foo5');
787+
$this->assertSame($foo5, $foo5->bar->foo);
785788
}
786789

787790
public function provideAlmostCircular()

src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,13 @@
4646
$container->register('foobar4', 'stdClass')->setPublic(true)
4747
->addArgument(new Reference('foo4'));
4848

49+
// loop on the constructor of a setter-injected dep with property
50+
51+
$container->register('foo5', 'stdClass')->setPublic(true)
52+
->setProperty('bar', new Reference('bar5'));
53+
54+
$container->register('bar5', 'stdClass')->setPublic($public)
55+
->addArgument(new Reference('foo5'))
56+
->setProperty('foo', new Reference('foo5'));
57+
4958
return $container;

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public function __construct()
2727
'bar3' => 'getBar3Service',
2828
'foo' => 'getFooService',
2929
'foo2' => 'getFoo2Service',
30+
'foo5' => 'getFoo5Service',
3031
'foobar4' => 'getFoobar4Service',
3132
);
3233

@@ -39,6 +40,7 @@ public function getRemovedIds()
3940
'Psr\\Container\\ContainerInterface' => true,
4041
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
4142
'bar' => true,
43+
'bar5' => true,
4244
'foo4' => true,
4345
'foobar' => true,
4446
'foobar2' => true,
@@ -125,6 +127,24 @@ protected function getFoo2Service()
125127
return $this->services['foo2'] = new \FooCircular($a);
126128
}
127129

130+
/**
131+
* Gets the public 'foo5' shared service.
132+
*
133+
* @return \stdClass
134+
*/
135+
protected function getFoo5Service()
136+
{
137+
$this->services['foo5'] = $instance = new \stdClass();
138+
139+
$a = new \stdClass(${($_ = isset($this->services['foo5']) ? $this->services['foo5'] : $this->getFoo5Service()) && false ?: '_'});
140+
141+
$a->foo = $instance;
142+
143+
$instance->bar = $a;
144+
145+
return $instance;
146+
}
147+
128148
/**
129149
* Gets the public 'foobar4' shared service.
130150
*

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ public function __construct()
2525
$this->methodMap = array(
2626
'bar' => 'getBarService',
2727
'bar3' => 'getBar3Service',
28+
'bar5' => 'getBar5Service',
2829
'foo' => 'getFooService',
2930
'foo2' => 'getFoo2Service',
3031
'foo4' => 'getFoo4Service',
32+
'foo5' => 'getFoo5Service',
3133
'foobar' => 'getFoobarService',
3234
'foobar2' => 'getFoobar2Service',
3335
'foobar3' => 'getFoobar3Service',
@@ -93,6 +95,26 @@ protected function getBar3Service()
9395
return $instance;
9496
}
9597

98+
/**
99+
* Gets the public 'bar5' shared service.
100+
*
101+
* @return \stdClass
102+
*/
103+
protected function getBar5Service()
104+
{
105+
$a = ${($_ = isset($this->services['foo5']) ? $this->services['foo5'] : $this->getFoo5Service()) && false ?: '_'};
106+
107+
if (isset($this->services['bar5'])) {
108+
return $this->services['bar5'];
109+
}
110+
111+
$this->services['bar5'] = $instance = new \stdClass($a);
112+
113+
$instance->foo = $a;
114+
115+
return $instance;
116+
}
117+
96118
/**
97119
* Gets the public 'foo' shared service.
98120
*
@@ -139,6 +161,20 @@ protected function getFoo4Service()
139161
return $instance;
140162
}
141163

164+
/**
165+
* Gets the public 'foo5' shared service.
166+
*
167+
* @return \stdClass
168+
*/
169+
protected function getFoo5Service()
170+
{
171+
$this->services['foo5'] = $instance = new \stdClass();
172+
173+
$instance->bar = ${($_ = isset($this->services['bar5']) ? $this->services['bar5'] : $this->getBar5Service()) && false ?: '_'};
174+
175+
return $instance;
176+
}
177+
142178
/**
143179
* Gets the public 'foobar' shared service.
144180
*

0 commit comments

Comments
 (0)