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

Appearance settings

Commit eca5db9

Browse filesBrowse files
[DI] Fix dumping some complex service graphs
1 parent edbd869 commit eca5db9
Copy full SHA for eca5db9

File tree

Expand file treeCollapse file tree

4 files changed

+148
-5
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+148
-5
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+9-5Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ private function addServiceInlinedDefinitions($id, Definition $definition, \SplO
516516

517517
$code .= $this->addNewInstance($def, '$'.$name, ' = ', $id);
518518

519-
if (!$this->hasReference($id, array($def->getProperties(), $def->getMethodCalls(), $def->getConfigurator()), true)) {
519+
if (!$this->hasReference($id, array($def->getProperties(), $def->getMethodCalls(), $def->getConfigurator()), true, $inlinedDefinitions)) {
520520
$code .= $this->addServiceProperties($def, $name);
521521
$code .= $this->addServiceMethodCalls($def, $name);
522522
$code .= $this->addServiceConfigurator($def, $name);
@@ -669,7 +669,7 @@ private function addServiceInlinedDefinitionsSetup($id, Definition $definition,
669669
{
670670
$code = '';
671671
foreach ($inlinedDefinitions as $def) {
672-
if ($definition === $def || !$this->hasReference($id, array($def->getProperties(), $def->getMethodCalls(), $def->getConfigurator()), true)) {
672+
if ($definition === $def || !$this->hasReference($id, array($def->getProperties(), $def->getMethodCalls(), $def->getConfigurator()), true, $inlinedDefinitions)) {
673673
continue;
674674
}
675675

@@ -812,6 +812,7 @@ protected function {$methodName}($lazyInitialization)
812812

813813
$inlinedDefinitions = $this->getDefinitionsFromArguments(array($definition));
814814
$constructorDefinitions = $this->getDefinitionsFromArguments(array($definition->getArguments(), $definition->getFactory()));
815+
unset($constructorDefinitions[$definition]); // ensures $definition will be last
815816
$otherDefinitions = new \SplObjectStorage();
816817
$serviceCalls = array();
817818

@@ -1635,15 +1636,15 @@ private function getDefinitionsFromArguments(array $arguments, $isConstructorArg
16351636
*
16361637
* @return bool
16371638
*/
1638-
private function hasReference($id, array $arguments, $deep = false, array &$visited = array())
1639+
private function hasReference($id, array $arguments, $deep = false, \SplObjectStorage $inlinedDefinitions = null, array &$visited = array())
16391640
{
16401641
if (!isset($this->circularReferences[$id])) {
16411642
return false;
16421643
}
16431644

16441645
foreach ($arguments as $argument) {
16451646
if (\is_array($argument)) {
1646-
if ($this->hasReference($id, $argument, $deep, $visited)) {
1647+
if ($this->hasReference($id, $argument, $deep, $inlinedDefinitions, $visited)) {
16471648
return true;
16481649
}
16491650

@@ -1662,6 +1663,9 @@ private function hasReference($id, array $arguments, $deep = false, array &$visi
16621663

16631664
$service = $this->container->getDefinition($argumentId);
16641665
} elseif ($argument instanceof Definition) {
1666+
if (isset($inlinedDefinitions[$argument])) {
1667+
return true;
1668+
}
16651669
$service = $argument;
16661670
} else {
16671671
continue;
@@ -1673,7 +1677,7 @@ private function hasReference($id, array $arguments, $deep = false, array &$visi
16731677
continue;
16741678
}
16751679

1676-
if ($this->hasReference($id, array($service->getArguments(), $service->getFactory(), $service->getProperties(), $service->getMethodCalls(), $service->getConfigurator()), $deep, $visited)) {
1680+
if ($this->hasReference($id, array($service->getArguments(), $service->getFactory(), $service->getProperties(), $service->getMethodCalls(), $service->getConfigurator()), $deep, $inlinedDefinitions, $visited)) {
16771681
return true;
16781682
}
16791683
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,21 @@ public function provideAlmostCircular()
838838
yield array('private');
839839
}
840840

841+
public function testDeepServiceGraph()
842+
{
843+
$container = new ContainerBuilder();
844+
845+
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
846+
$loader->load('services_deep_graph.yml');
847+
848+
$container->compile();
849+
850+
$dumper = new PhpDumper($container);
851+
$dumper->dump();
852+
853+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_deep_graph.php', $dumper->dump());
854+
}
855+
841856
public function testHotPathOptimizations()
842857
{
843858
$container = include self::$fixturesPath.'/containers/container_inline_requires.php';
+100Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
4+
use Symfony\Component\DependencyInjection\ContainerInterface;
5+
use Symfony\Component\DependencyInjection\Container;
6+
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
7+
use Symfony\Component\DependencyInjection\Exception\LogicException;
8+
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
9+
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
10+
11+
/**
12+
* This class has been auto-generated
13+
* by the Symfony Dependency Injection Component.
14+
*
15+
* @final since Symfony 3.3
16+
*/
17+
class ProjectServiceContainer extends Container
18+
{
19+
private $parameters;
20+
private $targetDirs = array();
21+
22+
public function __construct()
23+
{
24+
$this->services = array();
25+
$this->methodMap = array(
26+
'bar' => 'getBarService',
27+
'foo' => 'getFooService',
28+
);
29+
30+
$this->aliases = array();
31+
}
32+
33+
public function getRemovedIds()
34+
{
35+
return array(
36+
'1_c2d83go6s' => true,
37+
'2_c3d83go6s' => true,
38+
'3_c4d83go6s' => true,
39+
'4_c6d83go6s' => true,
40+
'Psr\\Container\\ContainerInterface' => true,
41+
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
42+
);
43+
}
44+
45+
public function compile()
46+
{
47+
throw new LogicException('You cannot compile a dumped container that was already compiled.');
48+
}
49+
50+
public function isCompiled()
51+
{
52+
return true;
53+
}
54+
55+
public function isFrozen()
56+
{
57+
@trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED);
58+
59+
return true;
60+
}
61+
62+
/**
63+
* Gets the public 'bar' shared service.
64+
*
65+
* @return \c5
66+
*/
67+
protected function getBarService()
68+
{
69+
$this->services['bar'] = $instance = new \c5();
70+
71+
$instance->p5 = new \c6(${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->getFooService()) && false ?: '_'});
72+
73+
return $instance;
74+
}
75+
76+
/**
77+
* Gets the public 'foo' shared service.
78+
*
79+
* @return \c1
80+
*/
81+
protected function getFooService()
82+
{
83+
$a = ${($_ = isset($this->services['bar']) ? $this->services['bar'] : $this->getBarService()) && false ?: '_'};
84+
85+
if (isset($this->services['foo'])) {
86+
return $this->services['foo'];
87+
}
88+
89+
$b = new \c2();
90+
91+
$this->services['foo'] = $instance = new \c1($a, $b);
92+
93+
$c = new \c3();
94+
95+
$c->p3 = new \c4();
96+
$b->p2 = $c;
97+
98+
return $instance;
99+
}
100+
}
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
services:
3+
foo:
4+
class: c1
5+
public: true
6+
arguments:
7+
- '@bar'
8+
- !service
9+
class: c2
10+
properties:
11+
p2: !service
12+
class: c3
13+
properties:
14+
p3: !service
15+
class: c4
16+
17+
bar:
18+
class: c5
19+
public: true
20+
properties:
21+
p5: !service
22+
class: c6
23+
arguments: ['@foo']
24+

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.