bug #21372 [DependencyInjection] Fixed variadic method parameter in autowired classes (brainexe)
This PR was squashed before being merged into the 3.1 branch (closes #21372).
Discussion
----------
[DependencyInjection] Fixed variadic method parameter in autowired classes
| Q | A
| ------------- | ---
| Branch? | 3.1
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | --
| License | MIT
Autowiring classes containing methods with variadic method parameter throws a ReflectionException in compile process:
```
PHP Fatal error: Uncaught ReflectionException: Internal error: Failed to retrieve the default value in /.../vendor/symfony/dependency-injection/Compiler/AutowirePass.php:437
Stack trace:
#0 /.../vendor/symfony/dependency-injection/Compiler/AutowirePass.php(437): ReflectionParameter->getDefaultValue()
#1 /.../vendor/symfony/dependency-injection/Compiler/AutowirePass.php(80): Symfony\Component\DependencyInjection\Compiler\AutowirePass::getResourceMetadataForMethod(Object(ReflectionMethod))
#2 /.../vendor/symfony/dependency-injection/Compiler/AutowirePass.php(105): Symfony\Component\DependencyInjection\Compiler\AutowirePass::createResourceForClass(Object(ReflectionClass))
#3 /.../vendor/symfony/dependency-injection/Compiler/AutowirePass.php(48): Symfony\Component\DependencyInjection\Compiler\AutowirePass->completeDefinition('__controller.Sw...', Object(Symfony\Component\DependencyInjection\Definition), Array)
#4 /.../vendor/symfony/dependency-injection/Compiler/Compiler in /.../vendor/symfony/dependency-injection/Compiler/AutowirePass.php on line 437
```
**Example:**
```
<?php
class FooVariadic
{
public function bar(...$arguments)
{
}
}
$method = new ReflectionMethod(FooVariadic::class, 'bar');
$parameter = $method->getParameters()[0];
$parameter->getDefaultValue(); // -> ReflectionException: Internal error: Failed to retrieve the default value in ...
```
Commits
-------
a7f63de414
[DependencyInjection] Fixed variadic method parameter in autowired classes
This commit is contained in:
commit
ed5eb6db54
@ -338,10 +338,11 @@ class AutowirePass implements CompilerPassInterface
|
||||
$class = false;
|
||||
}
|
||||
|
||||
$isVariadic = method_exists($parameter, 'isVariadic') && $parameter->isVariadic();
|
||||
$methodArgumentsMetadata[] = array(
|
||||
'class' => $class,
|
||||
'isOptional' => $parameter->isOptional(),
|
||||
'defaultValue' => $parameter->isOptional() ? $parameter->getDefaultValue() : null,
|
||||
'defaultValue' => ($parameter->isOptional() && !$isVariadic) ? $parameter->getDefaultValue() : null,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ namespace Symfony\Component\DependencyInjection\Tests\Compiler;
|
||||
use Symfony\Component\DependencyInjection\Compiler\AutowirePass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\includes\FooVariadic;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
@ -35,6 +36,23 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('foo', (string) $container->getDefinition('bar')->getArgument(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 5.6
|
||||
*/
|
||||
public function testProcessVariadic()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->register('foo', Foo::class);
|
||||
$definition = $container->register('fooVariadic', FooVariadic::class);
|
||||
$definition->setAutowired(true);
|
||||
|
||||
$pass = new AutowirePass();
|
||||
$pass->process($container);
|
||||
|
||||
$this->assertCount(1, $container->getDefinition('fooVariadic')->getArguments());
|
||||
$this->assertEquals('foo', (string) $container->getDefinition('fooVariadic')->getArgument(0));
|
||||
}
|
||||
|
||||
public function testProcessAutowireParent()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\includes;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Tests\Compiler\Foo;
|
||||
|
||||
class FooVariadic
|
||||
{
|
||||
public function __construct(Foo $foo)
|
||||
{
|
||||
}
|
||||
|
||||
public function bar(...$arguments)
|
||||
{
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user