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

[DI] Mixing constructor injection and setter injection breaks php dumper #28824

Copy link
Copy link
Closed
@discordier

Description

@discordier
Issue body actions

Symfony version(s) affected: 4.1 (since 4.1.5 - previous not affected)

Description
When having a "complex" service graph consisting a mixture of constructor injection and setter injection, the dumped function in the container will attempt to use a variable before initializing it.

The container will error out with something like:

Notice: Undefined variable: b

How to reproduce
I tried to reduce the amount of involved services to the absolute minimum, this is how far I got it narrowed down.
The following unit test breaks the container dumper on my machine.
Reducing it more, like removing any of the ->addMethodCall() declarations or any of the arguments of multiuse1, will not exhibit the issue anymore.

diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
index 8cb11568f2..2767fd9847 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
@@ -1071,6 +1071,49 @@ class PhpDumperTest extends TestCase
         $container = new \Symfony_DI_PhpDumper_Errored_Definition();
         $container->get('runtime_error');
     }
+
+    public function testCircularWithAddCalls()
+    {
+        $container = new ContainerBuilder();
+
+        $container
+            ->register('root', 'stdClass')
+            ->setArguments([new Reference('level2'), new Reference('multiuse1')])
+            ->setPublic(true);
+
+        $container
+            ->register('level2', FooForCircularWithAddCalls::class)
+            ->addMethodCall('call', [new Reference('level3')]);
+
+        $container->register('multiuse1', 'stdClass');
+
+        $container
+            ->register('level3', 'stdClass')
+            ->addArgument(new Reference('level4'));
+
+        $container
+            ->register('level4', 'stdClass')
+            ->setArguments([new Reference('multiuse1'), new Reference('level5')]);
+
+        $container
+            ->register('level5', 'stdClass')
+            ->addArgument(new Reference('level6'));
+
+        $container
+            ->register('level6', FooForCircularWithAddCalls::class)
+            ->addMethodCall('call', [new Reference('level5')]);
+
+        $container->compile();
+        $dumper = new PhpDumper($container);
+
+        $content = $dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Circular_With_Add_Calls'));
+
+        eval('?>'.$content);
+
+        $container = new \Symfony_DI_PhpDumper_Test_Circular_With_Add_Calls();
+
+        $this->assertInstanceOf(\stdClass::class, $container->get('root'));
+    }
 }
 
 class Rot13EnvVarProcessor implements EnvVarProcessorInterface
@@ -1096,3 +1139,10 @@ class FooForDeepGraph
         $this->bClone = clone $b;
     }
 }
+
+class FooForCircularWithAddCalls
+{
+    public function call(\stdClass $argument)
+    {
+    }
+}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

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