diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveNamedArgumentsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveNamedArgumentsPass.php index 75ea14a28a67b..70c643af64378 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveNamedArgumentsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveNamedArgumentsPass.php @@ -45,11 +45,19 @@ protected function processValue($value, $isRoot = false) $parameters = null; $resolvedArguments = array(); + $previousIndex = null; foreach ($arguments as $key => $argument) { if (is_int($key) || '' === $key || '$' !== $key[0]) { if (!is_int($key)) { @trigger_error(sprintf('Using key "%s" for defining arguments of method "%s" for service "%s" is deprecated since Symfony 3.3 and will throw an exception in 4.0. Use no keys or $named arguments instead.', $key, $method, $this->currentId), E_USER_DEPRECATED); + } else { + if (null !== $previousIndex && $key < $previousIndex) { + @trigger_error(sprintf('Using key "%s" after the key "%s" for defining arguments of method "%s" for service "%s" is deprecated since Symfony 3.3. They will be automatically reordered in 4.0.', $key, $previousIndex, $method, $this->currentId), E_USER_DEPRECATED); + } else { + $previousIndex = $key; + } } + $resolvedArguments[] = $argument; continue; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveNamedArgumentsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveNamedArgumentsPassTest.php index a933b950dff0d..07d4068875edb 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveNamedArgumentsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveNamedArgumentsPassTest.php @@ -91,6 +91,34 @@ public function testArgumentNotFound() $pass = new ResolveNamedArgumentsPass(); $pass->process($container); } + + /** + * @group legacy + * @expectedDeprecation Using key "0" after the key "1" for defining arguments of method "__construct" for service "Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy" is deprecated since Symfony 3.3. They will be automatically reordered in 4.0. + */ + public function testArgumentsWithManualIndexes() + { + $container = new ContainerBuilder(); + + $definition = $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class); + $definition->setArguments(array(1 => '123', 0 => new Reference('foo'))); + + $pass = new ResolveNamedArgumentsPass(); + $pass->process($container); + } + + public function testCase() + { + $container = new ContainerBuilder(); + + $definition = $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class); + $definition->setArguments(array('$apiKey' => '123', 0 => new Reference('foo'))); + + $pass = new ResolveNamedArgumentsPass(); + $pass->process($container); + + $this->assertEquals(array(1 => '123', 2 => new Reference('foo')), $definition->getArguments()); + } } class NoConstructor