拥有带有参数/自变量的PHP DI/IoC容器


Own PHP DI/IoC Container with parameters/arguments

我正在制作自己的练习框架,我一直使用DI/IoC容器,在构造函数中发送参数。

Container.php

class Container
{
    private $registry = array();
    private $shared = array();
    public function set($name, Closure $resolve)
    {
        if (!$this->exists($name)) {
            $this->registry[$name] = $resolve;
        } else {
            throw new Exception('Class with name ' . $name . ' is already registered.');
        }
    }
    public function get($name, $arguments = array())
    {
        if (!$this->exists($name, 'shared')) {
            $this->shared[$name] = $this->getNew($name, $arguments);
        }
        return $this->shared[$name];
    }
    public function getNew($name, $arguments = array())
    {
        if ($this->exists($name, 'registry')) {
            $class = $this->registry[$name];
            return $class();
        }
        throw new Exception('Class with name ' . $name . ' does not exist.');
    }
    private function exists($name, $type = 'registry')
    {
        return array_key_exists($name, $this->$type);
    }
}

用法:

$container = new Container;
$container->set('file', function() {
    return new Application'Library'File();
});
$container->set('cache', function($path, $type = 'json') use ($container) {
    return new Application'Library'Cache($container->get('file'), $path, $type);
});
$params = array (
    'path/to/cache/',
    'json'
);
$cache = $container->get('cache', $params);

问题是:如何使用get()getNew方法将参数/自变量发送到构造函数。我看到ReflectionClass($classname)newInstanceArgs($args)

编辑-也许是这样的东西:

public function getNew($name, $arguments = array())
{
    if ($this->exists($name, 'registry')) {
        if (count($arguments) > 0) {
            $object = new ReflectionClass($name);
            return $object->newInstanceArgs($arguments);
        } else {
            $class = $this->registry[$name];
            return $class();
        }
    }
    throw new Exception('Class with name ' . $name . ' does not exist.');
}

但它不起作用,因为为了创建Cache类,我只使用$container->get()和$params数组注入3个参数中的2个。第一个参数在$container->集合()中使用File类固定,并且在创建实例时不会正确注入。有什么解决办法吗?

错误:可捕获的致命错误:传递给Application''Library''Cache::__construct()的参数1必须是Application''Librarity''File的实例,字符串给定为

可行但我不满意的解决方案:

public function getNew($name, $arguments = array())
{
    if ($this->exists($name, 'registry')) {
        $class = $this->registry[$name];
        $count = count($arguments);
        switch ($count) {
            case 1:
                $object = $class($arguments[0]);
                break;
            case 2:
                $object = $class($arguments[0], $arguments[1]);
                break;
            case 3:
                $object = $class($arguments[0], $arguments[1], $arguments[2]);
                break;
            case 4:
                $object = $class($arguments[0], $arguments[1], $arguments[2], $arguments[3]);
                break;
            default:
                $object = $class();
                break;
        }
        return $object;
    }
    throw new Exception('Class with name ' . $name . ' does not exist.');
}

通过带有注入参数的$classname的开关大小写和返回实例,统计$arguments的数量。