From d6e2b8188c38865858218193c4cc7eec51c08c22 Mon Sep 17 00:00:00 2001 From: Javier Spagnoletti Date: Fri, 23 Feb 2018 00:16:20 -0300 Subject: [PATCH 1/2] Add entry for `container.dumper.inline_class_loader` param at `UPGRADE-3.4.md` and `UPGRADE-4.0.md` --- UPGRADE-3.4.md | 10 ++++++++++ UPGRADE-4.0.md | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/UPGRADE-3.4.md b/UPGRADE-3.4.md index 00d6422f76..2638d84c80 100644 --- a/UPGRADE-3.4.md +++ b/UPGRADE-3.4.md @@ -72,6 +72,16 @@ DependencyInjection * The `ResolveDefinitionTemplatesPass` class is deprecated and will be removed in 4.0. Use the `ResolveChildDefinitionsPass` class instead. + * Unless you're using a custom autoloader, you should enable the `container.dumper.inline_class_loader` + parameter. This can drastically improve DX by reducing the time to load classes + when the `DebugClassLoader` is enabled. If you're using `FrameworkBundle`, this + performance improvement will also impact the "dev" environment: + + ```yml + parameters: + container.dumper.inline_class_loader: true + ``` + Debug ----- diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md index 4eb1a0ed2a..4a6d02b374 100644 --- a/UPGRADE-4.0.md +++ b/UPGRADE-4.0.md @@ -236,6 +236,17 @@ DependencyInjection * The `ExtensionCompilerPass` has been moved to before-optimization passes with priority -1000. + * In 3.4, parameter `container.dumper.inline_class_loader` was introduced. Unless + you're using a custom autoloader, you should enable this parameter. This can + drastically improve DX by reducing the time to load classes when the `DebugClassLoader` + is enabled. If you're using `FrameworkBundle`, this performance improvement will + also impact the "dev" environment: + + ```yml + parameters: + container.dumper.inline_class_loader: true + ``` + DoctrineBridge -------------- From 4a5e43eae8c820742e40aba81fa4e6b8dbc9442a Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 1 Mar 2018 14:42:47 +0100 Subject: [PATCH 2/2] [DI] Fix missing "id" normalization when dumping the container --- .../Compiler/AnalyzeServiceReferencesPass.php | 15 +++++++------- .../Compiler/AutowirePass.php | 2 +- .../Compiler/DecoratorServicePass.php | 2 +- .../Compiler/FactoryReturnTypePass.php | 14 ++++++------- .../Compiler/InlineServiceDefinitionsPass.php | 2 +- .../RegisterServiceSubscribersPass.php | 2 +- .../ReplaceAliasByActualDefinitionPass.php | 4 ++-- .../Compiler/ResolveBindingsPass.php | 2 +- .../Compiler/ResolveHotPathPass.php | 2 +- .../Compiler/ResolveInvalidReferencesPass.php | 4 +--- .../ResolveReferencesToAliasesPass.php | 6 +++--- .../ResolveServiceSubscribersPass.php | 2 +- .../DependencyInjection/Container.php | 2 +- .../DependencyInjection/ContainerBuilder.php | 20 +++++++++++++++---- .../DependencyInjection/Dumper/PhpDumper.php | 14 +++++++------ .../ParameterBag/ParameterBag.php | 6 +++--- .../Tests/Dumper/PhpDumperTest.php | 20 +++++++++++++++++++ 17 files changed, 76 insertions(+), 43 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php index 23a5abc9f5..296051302d 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php @@ -64,7 +64,8 @@ class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements Repe $this->lazy = false; foreach ($container->getAliases() as $id => $alias) { - $this->graph->connect($id, $alias, (string) $alias, $this->getDefinition((string) $alias), null); + $targetId = $this->getDefinitionId((string) $alias); + $this->graph->connect($id, $alias, $targetId, $this->getDefinition($targetId), null); } parent::process($container); @@ -87,12 +88,13 @@ class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements Repe return $value; } if ($value instanceof Reference) { - $targetDefinition = $this->getDefinition((string) $value); + $targetId = $this->getDefinitionId((string) $value); + $targetDefinition = $this->getDefinition($targetId); $this->graph->connect( $this->currentId, $this->currentDefinition, - $this->getDefinitionId((string) $value), + $targetId, $targetDefinition, $value, $this->lazy || ($targetDefinition && $targetDefinition->isLazy()), @@ -134,8 +136,6 @@ class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements Repe */ private function getDefinition($id) { - $id = $this->getDefinitionId($id); - return null === $id ? null : $this->container->getDefinition($id); } @@ -149,7 +149,7 @@ class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements Repe return; } - return $id; + return $this->container->normalizeId($id); } private function getExpressionLanguage() @@ -163,11 +163,12 @@ class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements Repe $this->expressionLanguage = new ExpressionLanguage(null, $providers, function ($arg) { if ('""' === substr_replace($arg, '', 1, -1)) { $id = stripcslashes(substr($arg, 1, -1)); + $id = $this->getDefinitionId($id); $this->graph->connect( $this->currentId, $this->currentDefinition, - $this->getDefinitionId($id), + $id, $this->getDefinition($id) ); } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php index ae58f62bd0..59fa1b502c 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php @@ -281,7 +281,7 @@ class AutowirePass extends AbstractRecursivePass $this->lastFailure = null; $type = $reference->getType(); - if ($type !== (string) $reference || ($this->container->has($type) && !$this->container->findDefinition($type)->isAbstract())) { + if ($type !== $this->container->normalizeId($reference) || ($this->container->has($type) && !$this->container->findDefinition($type)->isAbstract())) { return $reference; } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php index 99234812d6..1976d0ac56 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php @@ -50,7 +50,7 @@ class DecoratorServicePass implements CompilerPassInterface $alias = $container->getAlias($inner); $public = $alias->isPublic(); $private = $alias->isPrivate(); - $container->setAlias($renamedId, new Alias((string) $alias, false)); + $container->setAlias($renamedId, new Alias($container->normalizeId($alias), false)); } else { $decoratedDefinition = $container->getDefinition($inner); $definition->setTags(array_merge($decoratedDefinition->getTags(), $definition->getTags())); diff --git a/src/Symfony/Component/DependencyInjection/Compiler/FactoryReturnTypePass.php b/src/Symfony/Component/DependencyInjection/Compiler/FactoryReturnTypePass.php index 91497086c2..825e117ccc 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/FactoryReturnTypePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/FactoryReturnTypePass.php @@ -51,13 +51,12 @@ class FactoryReturnTypePass implements CompilerPassInterface private function updateDefinition(ContainerBuilder $container, $id, Definition $definition, array $resolveClassPassChanges, array $previous = array()) { // circular reference - $lcId = strtolower($id); - if (isset($previous[$lcId])) { + if (isset($previous[$id])) { return; } $factory = $definition->getFactory(); - if (null === $factory || (!isset($resolveClassPassChanges[$lcId]) && null !== $definition->getClass())) { + if (null === $factory || (!isset($resolveClassPassChanges[$id]) && null !== $definition->getClass())) { return; } @@ -73,9 +72,10 @@ class FactoryReturnTypePass implements CompilerPassInterface } } else { if ($factory[0] instanceof Reference) { - $previous[$lcId] = true; - $factoryDefinition = $container->findDefinition((string) $factory[0]); - $this->updateDefinition($container, $factory[0], $factoryDefinition, $resolveClassPassChanges, $previous); + $previous[$id] = true; + $factoryId = $container->normalizeId($factory[0]); + $factoryDefinition = $container->findDefinition($factoryId); + $this->updateDefinition($container, $factoryId, $factoryDefinition, $resolveClassPassChanges, $previous); $class = $factoryDefinition->getClass(); } else { $class = $factory[0]; @@ -103,7 +103,7 @@ class FactoryReturnTypePass implements CompilerPassInterface } } - if (null !== $returnType && (!isset($resolveClassPassChanges[$lcId]) || $returnType !== $resolveClassPassChanges[$lcId])) { + if (null !== $returnType && (!isset($resolveClassPassChanges[$id]) || $returnType !== $resolveClassPassChanges[$id])) { @trigger_error(sprintf('Relying on its factory\'s return-type to define the class of service "%s" is deprecated since Symfony 3.3 and won\'t work in 4.0. Set the "class" attribute to "%s" on the service definition instead.', $id, $returnType), E_USER_DEPRECATED); } $definition->setClass($returnType); diff --git a/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php index c704891856..c64348ed1d 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php @@ -67,7 +67,7 @@ class InlineServiceDefinitionsPass extends AbstractRecursivePass implements Repe $value = clone $value; } - if (!$value instanceof Reference || !$this->container->hasDefinition($id = (string) $value)) { + if (!$value instanceof Reference || !$this->container->hasDefinition($id = $this->container->normalizeId($value))) { return parent::processValue($value, $isRoot); } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php b/src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php index 572eabb7d9..63cacfad83 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php @@ -85,7 +85,7 @@ class RegisterServiceSubscribersPass extends AbstractRecursivePass $serviceMap[$key] = new Reference($type); } - $subscriberMap[$key] = new TypedReference((string) $serviceMap[$key], $type, $declaringClass, $optionalBehavior ?: ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE); + $subscriberMap[$key] = new TypedReference($this->container->normalizeId($serviceMap[$key]), $type, $declaringClass, $optionalBehavior ?: ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE); unset($serviceMap[$key]); } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php index bc86e5ab9d..8e20676592 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php @@ -36,7 +36,7 @@ class ReplaceAliasByActualDefinitionPass extends AbstractRecursivePass $seenAliasTargets = array(); $replacements = array(); foreach ($container->getAliases() as $definitionId => $target) { - $targetId = (string) $target; + $targetId = $container->normalizeId($target); // Special case: leave this target alone if ('service_container' === $targetId) { continue; @@ -77,7 +77,7 @@ class ReplaceAliasByActualDefinitionPass extends AbstractRecursivePass */ protected function processValue($value, $isRoot = false) { - if ($value instanceof Reference && isset($this->replacements[$referenceId = (string) $value])) { + if ($value instanceof Reference && isset($this->replacements[$referenceId = $this->container->normalizeId($value)])) { // Perform the replacement $newId = $this->replacements[$referenceId]; $value = new Reference($newId, $value->getInvalidBehavior()); diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php index 73ca29d35f..63f2a470ba 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php @@ -49,7 +49,7 @@ class ResolveBindingsPass extends AbstractRecursivePass */ protected function processValue($value, $isRoot = false) { - if ($value instanceof TypedReference && $value->getType() === (string) $value) { + if ($value instanceof TypedReference && $value->getType() === $this->container->normalizeId($value)) { // Already checked $bindings = $this->container->getDefinition($this->currentId)->getBindings(); diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveHotPathPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveHotPathPass.php index 38e96d06f1..2888cf4d39 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveHotPathPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveHotPathPass.php @@ -55,7 +55,7 @@ class ResolveHotPathPass extends AbstractRecursivePass if ($value instanceof Definition && $isRoot && (isset($this->resolvedIds[$this->currentId]) || !$value->hasTag($this->tagName) || $value->isDeprecated())) { return $value->isDeprecated() ? $value->clearTag($this->tagName) : $value; } - if ($value instanceof Reference && ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior() && $this->container->has($id = (string) $value)) { + if ($value instanceof Reference && ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior() && $this->container->has($id = $this->container->normalizeId($value))) { $definition = $this->container->findDefinition($id); if (!$definition->hasTag($this->tagName) && !$definition->isDeprecated()) { $this->resolvedIds[$id] = true; diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php index cb05f90143..d60272b276 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php @@ -90,9 +90,7 @@ class ResolveInvalidReferencesPass implements CompilerPassInterface $value = array_values($value); } } elseif ($value instanceof Reference) { - $id = (string) $value; - - if ($this->container->has($id)) { + if ($this->container->has($value)) { return $value; } $invalidBehavior = $value->getInvalidBehavior(); diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php index a46c74fbb6..831d994536 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php @@ -30,7 +30,7 @@ class ResolveReferencesToAliasesPass extends AbstractRecursivePass parent::process($container); foreach ($container->getAliases() as $id => $alias) { - $aliasId = (string) $alias; + $aliasId = $container->normalizeId($alias); if ($aliasId !== $defId = $this->getDefinitionId($aliasId, $container)) { $container->setAlias($id, $defId)->setPublic($alias->isPublic())->setPrivate($alias->isPrivate()); } @@ -43,7 +43,7 @@ class ResolveReferencesToAliasesPass extends AbstractRecursivePass protected function processValue($value, $isRoot = false) { if ($value instanceof Reference) { - $defId = $this->getDefinitionId($id = (string) $value, $this->container); + $defId = $this->getDefinitionId($id = $this->container->normalizeId($value), $this->container); if ($defId !== $id) { return new Reference($defId, $value->getInvalidBehavior()); @@ -69,7 +69,7 @@ class ResolveReferencesToAliasesPass extends AbstractRecursivePass throw new ServiceCircularReferenceException($id, array_keys($seen)); } $seen[$id] = true; - $id = (string) $container->getAlias($id); + $id = $container->normalizeId($container->getAlias($id)); } return $id; diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveServiceSubscribersPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveServiceSubscribersPass.php index 9245f21f74..bde9433690 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveServiceSubscribersPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveServiceSubscribersPass.php @@ -26,7 +26,7 @@ class ResolveServiceSubscribersPass extends AbstractRecursivePass protected function processValue($value, $isRoot = false) { - if ($value instanceof Reference && $this->serviceLocator && ContainerInterface::class === (string) $value) { + if ($value instanceof Reference && $this->serviceLocator && ContainerInterface::class === $this->container->normalizeId($value)) { return new Reference($this->serviceLocator); } diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index aa714728cd..5ca9b25adc 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -507,7 +507,7 @@ class Container implements ResettableContainerInterface */ public function normalizeId($id) { - if (!is_string($id)) { + if (!\is_string($id)) { $id = (string) $id; } if (isset($this->normalizedIds[$normalizedId = strtolower($id)])) { diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 6e025387f5..678aa37e08 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -627,7 +627,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface * * @throws BadMethodCallException When this ContainerBuilder is compiled */ - public function merge(ContainerBuilder $container) + public function merge(self $container) { if ($this->isCompiled()) { throw new BadMethodCallException('Cannot merge on a compiled container.'); @@ -1373,16 +1373,16 @@ class ContainerBuilder extends Container implements TaggedContainerInterface $value = $bag->resolveValue($value); } - if (is_array($value)) { + if (\is_array($value)) { $result = array(); foreach ($value as $k => $v) { - $result[$this->resolveEnvPlaceholders($k, $format, $usedEnvs)] = $this->resolveEnvPlaceholders($v, $format, $usedEnvs); + $result[\is_string($k) ? $this->resolveEnvPlaceholders($k, $format, $usedEnvs) : $k] = $this->resolveEnvPlaceholders($v, $format, $usedEnvs); } return $result; } - if (!is_string($value)) { + if (!\is_string($value) || 38 > \strlen($value)) { return $value; } $envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders; @@ -1455,6 +1455,18 @@ class ContainerBuilder extends Container implements TaggedContainerInterface $this->getCompiler()->log($pass, $message); } + /** + * {@inheritdoc} + */ + public function normalizeId($id) + { + if (!\is_string($id)) { + $id = (string) $id; + } + + return isset($this->definitions[$id]) || isset($this->aliasDefinitions[$id]) || isset($this->removedIds[$id]) ? $id : parent::normalizeId($id); + } + /** * Returns the Service Conditionals. * diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 9461e1ccb5..f4aa0582f7 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1232,9 +1232,9 @@ EOF; $code = " \$this->aliases = array(\n"; ksort($aliases); foreach ($aliases as $alias => $id) { - $id = (string) $id; + $id = $this->container->normalizeId($id); while (isset($aliases[$id])) { - $id = (string) $aliases[$id]; + $id = $this->container->normalizeId($aliases[$id]); } $code .= ' '.$this->doExport($alias).' => '.$this->doExport($id).",\n"; } @@ -1555,7 +1555,7 @@ EOF; if (is_array($argument)) { $this->getServiceCallsFromArguments($argument, $calls, $isPreInstance, $callerId, $behavior, $step); } elseif ($argument instanceof Reference) { - $id = (string) $argument; + $id = $this->container->normalizeId($argument); if (!isset($calls[$id])) { $calls[$id] = (int) ($isPreInstance && isset($this->circularReferences[$callerId][$id])); @@ -1625,7 +1625,7 @@ EOF; continue; } elseif ($argument instanceof Reference) { - $argumentId = (string) $argument; + $argumentId = $this->container->normalizeId($argument); if ($id === $argumentId) { return true; } @@ -1790,11 +1790,12 @@ EOF; } elseif ($value instanceof Variable) { return '$'.$value; } elseif ($value instanceof Reference) { - if (null !== $this->referenceVariables && isset($this->referenceVariables[$id = (string) $value])) { + $id = $this->container->normalizeId($value); + if (null !== $this->referenceVariables && isset($this->referenceVariables[$id])) { return $this->dumpValue($this->referenceVariables[$id], $interpolate); } - return $this->getServiceCall((string) $value, $value); + return $this->getServiceCall($id, $value); } elseif ($value instanceof Expression) { return $this->getExpressionLanguage()->compile((string) $value, array('this' => 'container')); } elseif ($value instanceof Parameter) { @@ -1881,6 +1882,7 @@ EOF; while ($this->container->hasAlias($id)) { $id = (string) $this->container->getAlias($id); } + $id = $this->container->normalizeId($id); if ('service_container' === $id) { return '$this'; diff --git a/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php b/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php index 257c433430..bb3e211025 100644 --- a/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php +++ b/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php @@ -173,16 +173,16 @@ class ParameterBag implements ParameterBagInterface */ public function resolveValue($value, array $resolving = array()) { - if (is_array($value)) { + if (\is_array($value)) { $args = array(); foreach ($value as $k => $v) { - $args[$this->resolveValue($k, $resolving)] = $this->resolveValue($v, $resolving); + $args[\is_string($k) ? $this->resolveValue($k, $resolving) : $k] = $this->resolveValue($v, $resolving); } return $args; } - if (!is_string($value)) { + if (!\is_string($value) || 2 > \strlen($value)) { return $value; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index f12fc608c9..56046e735b 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -1001,6 +1001,26 @@ class PhpDumperTest extends TestCase $this->assertSame('bar', $container->getParameter('FOO')); } + + /** + * @group legacy + * @expectedDeprecation Service identifiers will be made case sensitive in Symfony 4.0. Using "foo" instead of "Foo" is deprecated since Symfony 3.3. + * @expectedDeprecation The "Foo" service is deprecated. You should stop using it, as it will soon be removed. + */ + public function testReferenceWithLowerCaseId() + { + $container = new ContainerBuilder(); + $container->register('Bar', 'stdClass')->setProperty('foo', new Reference('foo'))->setPublic(true); + $container->register('Foo', 'stdClass')->setDeprecated(); + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Reference_With_Lower_Case_Id'))); + + $container = new \Symfony_DI_PhpDumper_Test_Reference_With_Lower_Case_Id(); + + $this->assertEquals((object) array('foo' => (object) array()), $container->get('Bar')); + } } class Rot13EnvVarProcessor implements EnvVarProcessorInterface