diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index c86f2cf..2ae2ec1 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -4,6 +4,7 @@ Yii Framework 2 Change Log 2.0.13 under development ------------------------ +- Enh #14126: Added variadic parameters support to DI container (SamMousa) - Enh #14087: Added `yii\web\View::registerCsrfMetaTags()` method that registers CSRF tags dynamically ensuring that caching doesn't interfere (RobinKamps) - Bug #6526: Fixed `yii\db\Command::batchInsert()` casting of double values correctly independent of the locale (cebe, leammas) - Bug #7890: Allow `migrate/mark` to mark history at the point of the base migration (cebe) diff --git a/framework/di/Container.php b/framework/di/Container.php index b481ffe..eed2aa8 100644 --- a/framework/di/Container.php +++ b/framework/di/Container.php @@ -256,7 +256,6 @@ class Container extends Component unset($this->_singletons[$class]); return $this; } - /** * Registers a class definition with this container and marks the class as a singleton class. * @@ -429,7 +428,9 @@ class Container extends Component $constructor = $reflection->getConstructor(); if ($constructor !== null) { foreach ($constructor->getParameters() as $param) { - if ($param->isDefaultValueAvailable()) { + if (version_compare(PHP_VERSION, '5.6.0', '>=') && $param->isVariadic()) { + break; + } elseif ($param->isDefaultValueAvailable()) { $dependencies[] = $param->getDefaultValue(); } else { $c = $param->getClass(); @@ -532,7 +533,10 @@ class Container extends Component $name = $param->getName(); if (($class = $param->getClass()) !== null) { $className = $class->getName(); - if ($associative && isset($params[$name]) && $params[$name] instanceof $className) { + if (version_compare(PHP_VERSION, '5.6.0', '>=') && $param->isVariadic()) { + $args = array_merge($args, array_values($params)); + break; + } elseif ($associative && isset($params[$name]) && $params[$name] instanceof $className) { $args[] = $params[$name]; unset($params[$name]); } elseif (!$associative && isset($params[0]) && $params[0] instanceof $className) { diff --git a/tests/framework/di/ContainerTest.php b/tests/framework/di/ContainerTest.php index 48609bd..9d8b674 100644 --- a/tests/framework/di/ContainerTest.php +++ b/tests/framework/di/ContainerTest.php @@ -18,6 +18,7 @@ use yiiunit\framework\di\stubs\Bar; use yiiunit\framework\di\stubs\Foo; use yiiunit\framework\di\stubs\Qux; use yiiunit\framework\di\stubs\QuxInterface; +use yiiunit\framework\di\stubs\Variadic; use yiiunit\TestCase; /** @@ -285,4 +286,21 @@ class ContainerTest extends TestCase $sameFoo = $container->get('qux.using.closure'); $this->assertSame($foo, $sameFoo); } + + /** + * @requires PHP 5.6 + */ + public function testVariadicConstructor() + { + $container = new Container(); + $container->get(Variadic::class); + } + + /** + * @requires PHP 5.6 + */ + public function testVariadicCallable() + { + require __DIR__ . '/testContainerWithVariadicCallable.php'; + } } diff --git a/tests/framework/di/stubs/Variadic.php b/tests/framework/di/stubs/Variadic.php new file mode 100644 index 0000000..329127f --- /dev/null +++ b/tests/framework/di/stubs/Variadic.php @@ -0,0 +1,24 @@ + + * @since 2.0.13 + */ +class Variadic +{ + public function __construct(QuxInterface ...$quxes) + { + + } + + +} diff --git a/tests/framework/di/testContainerWithVariadicCallable.php b/tests/framework/di/testContainerWithVariadicCallable.php new file mode 100644 index 0000000..c034643 --- /dev/null +++ b/tests/framework/di/testContainerWithVariadicCallable.php @@ -0,0 +1,15 @@ +invoke($func);