bug #25354 [DI] Fix non-string class handling in PhpDumper (nicolas-grekas, sroze)

This PR was merged into the 3.4 branch.

Discussion
----------

[DI] Fix non-string class handling in PhpDumper

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #25353
| License       | MIT
| Doc PR        | -

Commits
-------

28f00866b1 Ensure that inlined services with parameterized class name can be dumped
730b156f35 [DI] Fix non-string class handling in PhpDumper
This commit is contained in:
Fabien Potencier 2017-12-07 18:43:43 -08:00
commit ecf54d5aa0
2 changed files with 29 additions and 3 deletions

View File

@ -413,7 +413,7 @@ EOTXT;
if ($this->inlineRequires && !$this->isHotPath($definition)) {
$lineage = $calls = $behavior = array();
foreach ($inlinedDefinitions as $def) {
if (!$def->isDeprecated() && $class = is_array($factory = $def->getFactory()) && is_string($factory[0]) ? $factory[0] : $def->getClass()) {
if (!$def->isDeprecated() && is_string($class = is_array($factory = $def->getFactory()) && is_string($factory[0]) ? $factory[0] : $def->getClass())) {
$this->collectLineage($class, $lineage);
}
$arguments = array($def->getArguments(), $def->getFactory(), $def->getProperties(), $def->getMethodCalls(), $def->getConfigurator());
@ -425,7 +425,7 @@ EOTXT;
&& ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $behavior[$id]
&& $this->container->has($id)
&& $this->isTrivialInstance($def = $this->container->findDefinition($id))
&& $class = is_array($factory = $def->getFactory()) && is_string($factory[0]) ? $factory[0] : $def->getClass()
&& is_string($class = is_array($factory = $def->getFactory()) && is_string($factory[0]) ? $factory[0] : $def->getClass())
) {
$this->collectLineage($class, $lineage);
}
@ -1226,7 +1226,7 @@ EOF;
$inlinedDefinitions = $this->getDefinitionsFromArguments(array($definition));
foreach ($inlinedDefinitions as $def) {
if ($class = is_array($factory = $def->getFactory()) && is_string($factory[0]) ? $factory[0] : $def->getClass()) {
if (is_string($class = is_array($factory = $def->getFactory()) && is_string($factory[0]) ? $factory[0] : $def->getClass())) {
$this->collectLineage($class, $lineage);
}
}

View File

@ -23,6 +23,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface;
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
use Symfony\Component\DependencyInjection\EnvVarProcessorInterface;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator;
@ -822,6 +823,31 @@ class PhpDumperTest extends TestCase
$this->assertInstanceOf('stdClass', $container->get('foo'));
}
public function testDumpHandlesObjectClassNames()
{
$container = new ContainerBuilder(new ParameterBag(array(
'class' => 'stdClass',
)));
$container->setDefinition('foo', new Definition(new Parameter('class')));
$container->setDefinition('bar', new Definition('stdClass', array(
new Reference('foo'),
)))->setPublic(true);
$container->setParameter('inline_requires', true);
$container->compile();
$dumper = new PhpDumper($container);
eval('?>'.$dumper->dump(array(
'class' => 'Symfony_DI_PhpDumper_Test_Object_Class_Name',
'inline_class_loader_parameter' => 'inline_requires',
)));
$container = new \Symfony_DI_PhpDumper_Test_Object_Class_Name();
$this->assertInstanceOf('stdClass', $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.