Browse Source

Fixes #14126: Added variadic parameters support to DI container

tags/2.0.13
Sam 7 years ago committed by Alexander Makarov
parent
commit
537317fbb1
  1. 1
      framework/CHANGELOG.md
  2. 10
      framework/di/Container.php
  3. 18
      tests/framework/di/ContainerTest.php
  4. 24
      tests/framework/di/stubs/Variadic.php
  5. 15
      tests/framework/di/testContainerWithVariadicCallable.php

1
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)

10
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) {

18
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';
}
}

24
tests/framework/di/stubs/Variadic.php

@ -0,0 +1,24 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yiiunit\framework\di\stubs;
use yii\base\Object;
/**
* @author Sam Mousa <sam@mousa.nl>
* @since 2.0.13
*/
class Variadic
{
public function __construct(QuxInterface ...$quxes)
{
}
}

15
tests/framework/di/testContainerWithVariadicCallable.php

@ -0,0 +1,15 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
use yii\di\Container;
use yiiunit\framework\di\stubs\QuxInterface;
$container = new Container();
$func = function(QuxInterface ...$quxes) {
return "That's a whole lot of quxes!";
};
$container->invoke($func);
Loading…
Cancel
Save