Skip to content

Commit adeab15

Browse files
committed
bug symfony#23605 [DI][Bug] Autowiring thinks optional args on core classes are required (weaverryan)
This PR was merged into the 3.3 branch. Discussion ---------- [DI][Bug] Autowiring thinks optional args on core classes are required | Q | A | ------------- | --- | Branch? | 3,3 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | none | License | MIT | Doc PR | n/a Currently, the following fails: ```yml services: PDO: class: PDO arguments: - 'sqlite:/foo.db' ``` The error: > Cannot autowire service "PDO": argument "$username" of method "__construct()" must have a type-hint or be given a value explicitly `$username` is the second argument to `PDO`, and it's optional. Here's the reason: it appears that `$parameter->isDefaultValueAvailable()` returns false for optional arguments of core classes. But, `$parameter->isOptional()` returns true. This allows optional arguments to not throw an exception. I can't think of any edge cases this will cause - but it's possible I'm not thinking of something :). Cheers! Commits ------- 178a0f7 Fixing a bug where if a core class was autowired, autowiring tried to autowire optional args as if they were required
2 parents 444a840 + 178a0f7 commit adeab15

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,12 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
273273

274274
// no default value? Then fail
275275
if (!$parameter->isDefaultValueAvailable()) {
276+
// For core classes, isDefaultValueAvailable() can
277+
// be false when isOptional() returns true. If the
278+
// argument *is* optional, allow it to be missing
279+
if ($parameter->isOptional()) {
280+
continue;
281+
}
276282
throw new AutowiringFailedException($this->currentId, sprintf('Cannot autowire service "%s": argument "$%s" of method "%s()" must have a type-hint or be given a value explicitly.', $this->currentId, $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method));
277283
}
278284

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,23 @@ public function testOptionalScalarArgsNotPassedIfLast()
512512
);
513513
}
514514

515+
public function testOptionalArgsNoRequiredForCoreClasses()
516+
{
517+
$container = new ContainerBuilder();
518+
519+
$container->register('pdo_service', \PDO::class)
520+
->addArgument('sqlite:/foo.db')
521+
->setAutowired(true);
522+
523+
(new AutowirePass())->process($container);
524+
525+
$definition = $container->getDefinition('pdo_service');
526+
$this->assertEquals(
527+
array('sqlite:/foo.db'),
528+
$definition->getArguments()
529+
);
530+
}
531+
515532
public function testSetterInjection()
516533
{
517534
$container = new ContainerBuilder();

0 commit comments

Comments
 (0)