Skip to content

Commit 45d614d

Browse files
[DependencyInjection] Fix order of arguments when mixing positional and named ones
1 parent ef26e93 commit 45d614d

File tree

4 files changed

+55
-2
lines changed

4 files changed

+55
-2
lines changed

src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
240240
foreach ($parameters as $index => $parameter) {
241241
$this->defaultArgument->names[$index] = $parameter->name;
242242

243+
if (\array_key_exists($parameter->name, $arguments)) {
244+
$arguments[$index] = $arguments[$parameter->name];
245+
unset($arguments[$parameter->name]);
246+
}
243247
if (\array_key_exists($index, $arguments) && '' !== $arguments[$index]) {
244248
continue;
245249
}
@@ -341,7 +345,7 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
341345

342346
// it's possible index 1 was set, then index 0, then 2, etc
343347
// make sure that we re-order so they're injected as expected
344-
ksort($arguments);
348+
ksort($arguments, \SORT_NATURAL);
345349

346350
return $arguments;
347351
}

src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,17 @@ protected function processValue($value, bool $isRoot = false)
177177
}
178178
}
179179

180+
$names = [];
181+
180182
foreach ($reflectionMethod->getParameters() as $key => $parameter) {
183+
$names[$key] = $parameter->name;
184+
181185
if (\array_key_exists($key, $arguments) && '' !== $arguments[$key]) {
182186
continue;
183187
}
188+
if (\array_key_exists($parameter->name, $arguments) && '' !== $arguments[$parameter->name]) {
189+
continue;
190+
}
184191

185192
$typeHint = ProxyHelper::getTypeHint($reflectionMethod, $parameter);
186193
$name = Target::parseName($parameter);
@@ -210,8 +217,15 @@ protected function processValue($value, bool $isRoot = false)
210217
}
211218
}
212219

220+
foreach ($names as $key => $name) {
221+
if (\array_key_exists($name, $arguments) && (0 === $key || \array_key_exists($key - 1, $arguments))) {
222+
$arguments[$key] = $arguments[$name];
223+
unset($arguments[$name]);
224+
}
225+
}
226+
213227
if ($arguments !== $call[1]) {
214-
ksort($arguments);
228+
ksort($arguments, \SORT_NATURAL);
215229
$calls[$i][1] = $arguments;
216230
}
217231
}

src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,4 +1204,19 @@ public function testDecorationWithServiceAndAliasedInterface()
12041204
static::assertInstanceOf(DecoratedDecorator::class, $container->get(DecoratorInterface::class));
12051205
static::assertInstanceOf(DecoratedDecorator::class, $container->get(DecoratorImpl::class));
12061206
}
1207+
1208+
public function testAutowireWithNamedArgs()
1209+
{
1210+
$container = new ContainerBuilder();
1211+
1212+
$container->register('foo', MultipleArgumentsOptionalScalar::class)
1213+
->setArguments(['foo' => 'abc'])
1214+
->setAutowired(true)
1215+
->setPublic(true);
1216+
$container->register(A::class, A::class);
1217+
1218+
(new AutowirePass())->process($container);
1219+
1220+
$this->assertEquals([new TypedReference(A::class, A::class), 'abc'], $container->getDefinition('foo')->getArguments());
1221+
}
12071222
}

src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,4 +249,24 @@ public function testBindWithTarget()
249249

250250
$this->assertSame('bar', (string) $container->getDefinition('with_target')->getArgument(0));
251251
}
252+
253+
public function testBindWithNamedArgs()
254+
{
255+
$container = new ContainerBuilder();
256+
257+
$bindings = [
258+
'$apiKey' => new BoundArgument('K'),
259+
];
260+
261+
$definition = $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class);
262+
$definition->setArguments(['c' => 'C', 'hostName' => 'H']);
263+
$definition->setBindings($bindings);
264+
265+
$container->register('foo', CaseSensitiveClass::class);
266+
267+
$pass = new ResolveBindingsPass();
268+
$pass->process($container);
269+
270+
$this->assertEquals(['C', 'K', 'H'], $definition->getArguments());
271+
}
252272
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy