[DI] Fix dumping ignore-on-uninitialized references to synthetic services

This commit is contained in:
Nicolas Grekas 2018-06-30 09:08:55 +02:00
parent 493ce7a64b
commit 97e8d68a05
3 changed files with 42 additions and 2 deletions

View File

@ -1898,8 +1898,10 @@ EOF;
return '$this';
}
if ($this->container->hasDefinition($id) && ($definition = $this->container->getDefinition($id)) && !$definition->isSynthetic()) {
if (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) {
if ($this->container->hasDefinition($id) && $definition = $this->container->getDefinition($id)) {
if ($definition->isSynthetic()) {
$code = sprintf('$this->get(\'%s\'%s)', $id, null !== $reference ? ', '.$reference->getInvalidBehavior() : '');
} elseif (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) {
$code = 'null';
if (!$definition->isShared()) {
return $code;

View File

@ -1434,6 +1434,21 @@ class ContainerBuilderTest extends TestCase
$this->assertSame('via-argument', $container->get('foo')->class1->identifier);
$this->assertSame('via-bindings', $container->get('foo')->class2->identifier);
}
public function testUninitializedSyntheticReference()
{
$container = new ContainerBuilder();
$container->register('foo', 'stdClass')->setPublic(true)->setSynthetic(true);
$container->register('bar', 'stdClass')->setPublic(true)->setShared(false)
->setProperty('foo', new Reference('foo', ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE));
$container->compile();
$this->assertEquals((object) array('foo' => null), $container->get('bar'));
$container->set('foo', (object) array(123));
$this->assertEquals((object) array('foo' => (object) array(123)), $container->get('bar'));
}
}
class FooClass

View File

@ -913,6 +913,29 @@ class PhpDumperTest extends TestCase
$this->assertInstanceOf('stdClass', $container->get('bar'));
}
public function testUninitializedSyntheticReference()
{
$container = new ContainerBuilder();
$container->register('foo', 'stdClass')->setPublic(true)->setSynthetic(true);
$container->register('bar', 'stdClass')->setPublic(true)->setShared(false)
->setProperty('foo', new Reference('foo', ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE));
$container->compile();
$dumper = new PhpDumper($container);
eval('?>'.$dumper->dump(array(
'class' => 'Symfony_DI_PhpDumper_Test_UninitializedSyntheticReference',
'inline_class_loader_parameter' => 'inline_requires',
)));
$container = new \Symfony_DI_PhpDumper_Test_UninitializedSyntheticReference();
$this->assertEquals((object) array('foo' => null), $container->get('bar'));
$container->set('foo', (object) array(123));
$this->assertEquals((object) array('foo' => (object) array(123)), $container->get('bar'));
}
/**
* @group legacy
* @expectedDeprecation The "private" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead.