8000 bug #48926 [DependencyInjection] Fix support for named arguments on n… · symfony/symfony@22b5860 · GitHub
[go: up one dir, main page]

Skip to content

Commit 22b5860

Browse files
bug #48926 [DependencyInjection] Fix support for named arguments on non-autowired services (nicolas-grekas)
This PR was merged into the 5.4 branch. Discussion ---------- [DependencyInjection] Fix support for named arguments on non-autowired services | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #48818 | License | MIT | Doc PR | - This fixes support for named arguments on non-autowired services as described in #48818. Related to #43277 and #38091 Commits ------- a899bed [DependencyInjection] Fix support for named arguments on non-autowired services
2 parents 003ccbd + a899bed commit 22b5860

File tree

4 files changed

+43
-2
lines changed

4 files changed

+43
-2
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ protected function processValue($value, bool $isRoot = false)
4343
foreach ($calls as $i => $call) {
4444
[$method, $arguments] = $call;
4545
$parameters = null;
46+
$resolvedKeys = [];
4647
$resolvedArguments = [];
4748

4849
foreach ($arguments as $key => $argument) {
@@ -51,6 +52,7 @@ protected function processValue($value, bool $isRoot = false)
5152
}
5253

5354
if (\is_int($key)) {
55+
$resolvedKeys[$key] = $key;
5456
$resolvedArguments[$key] = $argument;
5557
continue;
5658
}
@@ -71,9 +73,11 @@ protected function processValue($value, bool $isRoot = false)
7173
if ($key === '$'.$p->name) {
7274
if ($p->isVariadic() && \is_array($argument)) {
7375
foreach ($argument as $variadicArgument) {
76+
$resolvedKeys[$j] = $j;
7477
$resolvedArguments[$j++] = $variadicArgument;
7578
}
7679
} else {
80+
$resolvedKeys[$j] = $p->name;
7781
$resolvedArguments[$j] = $argument;
7882
}
7983

@@ -91,6 +95,7 @@ protected function processValue($value, bool $isRoot = false)
9195
$typeFound = false;
9296
foreach ($parameters as $j => $p) {
9397
if (!\array_key_exists($j, $resolvedArguments) && ProxyHelper::getTypeHint($r, $p, true) === $key) {
98+
$resolvedKeys[$j] = $p->name;
9499
$resolvedArguments[$j] = $argument;
95100
$typeFound = true;
96101
}
@@ -103,6 +108,12 @@ protected function processValue($value, bool $isRoot = false)
103108

104109
if ($resolvedArguments !== $call[1]) {
105110
ksort($resolvedArguments);
111+
112+
if (!$value->isAutowired() && !array_is_list($resolvedArguments)) {
113+
ksort($resolvedKeys);
114+
$resolvedArguments = array_combine($resolvedKeys, $resolvedArguments);
115+
}
116+
106117
$calls[$i][1] = $resolvedArguments;
107118
}
108119
}

src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1102,7 +1102,7 @@ private function createService(Definition $definition, array &$inlineServices, b
11021102
} else {
11031103
$r = new \ReflectionClass($parameterBag->resolveValue($definition->getClass()));
11041104

1105-
$service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs(array_values($arguments));
1105+
$service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments);
11061106

11071107
if (!$definition->isDeprecated() && 0 < strpos($r->getDocComment(), "\n * @deprecated ")) {
11081108
trigger_deprecation('', '', 'The "%s" service relies on the deprecated "%s" class. It should either be deprecated or its implementation upgraded.', $id, $r->name);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public function testInterfaceTypedArgument()
165165
$pass = new ResolveNamedArgumentsPass();
166166
$pass->process($container);
167167

168-
$this->assertSame($expected, $definition->getArgument(3));
168+
$this->assertSame($expected, $definition->getArgument('container'));
169169
}
170170

171171
public function testResolvesMultipleArgumentsOfTheSameType()

src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,6 +1773,24 @@ public function testFindTags()
17731773

17741774
$this->assertSame(['tag1', 'tag2', 'tag3'], $container->findTags());
17751775
}
1776+
1777+
/**
1778+
* @requires PHP 8
1779+
*/
1780+
public function testNamedArgument()
1781+
{
1782+
$container = new ContainerBuilder();
1783+
$container->register(E::class)
1784+
->setPublic(true)
1785+
->setArguments(['$second' => 2]);
1786+
1787+
$container->compile();
1788+
1789+
$e = $container->get(E::class);
1790+
1791+
$this->assertSame('', $e->first);
1792+
$this->assertSame(2, $e->second);
1793+
}
17761794
}
17771795

17781796
class FooClass
@@ -1801,3 +1819,15 @@ class C implements X
18011819
class D implements X
18021820
{
18031821
}
1822+
1823+
class E
1824+
{
1825+
public $first;
1826+
public $second;
1827+
1828+
public function __construct($first = '', $second = '')
1829+
{
1830+
$this->first = $first;
1831+
$this->second = $second;
1832+
}
1833+
}

0 commit comments

Comments
 (0)
0