Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/250.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP自动连线依赖项_Php_Dependency Injection - Fatal编程技术网

PHP自动连线依赖项

PHP自动连线依赖项,php,dependency-injection,Php,Dependency Injection,我正在尝试构建一个依赖项注入容器,它可以使用类型提示自动连接依赖项。当依赖项有自己的依赖项时,问题就会出现。换句话说,我希望依赖项容器能够处理无限嵌套的依赖项 foo Object ( [bar] => Bar Object ( [foobar] => foobar Object ( ) ) ) 例如,自动布线这一类将很容易: class Bar {

我正在尝试构建一个依赖项注入容器,它可以使用类型提示自动连接依赖项。当依赖项有自己的依赖项时,问题就会出现。换句话说,我希望依赖项容器能够处理无限嵌套的依赖项

foo Object
(
    [bar] => Bar Object
        (
            [foobar] => foobar Object
                (
                )

        )

)
例如,自动布线这一类将很容易:

class Bar
{
    public function __construct(Foobar $foobar)
    {
        $this->foobar = $foobar;
    }

}

class foo
{
    public function __construct(Bar $bar)
    {
        $this->bar = $bar;
    }
}
现在,如果bar也有依赖项,我必须以某种方式将foobar注入bar,然后再将bar注入foo

class foobar
{

}

class Bar
{
    public function __construct(Foobar $foobar)
    {
        $this->foobar = $foobar;
    }

}


class foo
{
    public function __construct(Bar $bar)
    {
        $this->bar = $bar;
    }
}

实现这一点需要两件事:递归和

以下是一个工作示例:

function instantiate($class_name) {
    $reflection = new ReflectionClass($class_name);
    $constructor = $reflection->getConstructor();

    // If there is no constructor in class, return object as is
    if(!$constructor) return $reflection->newInstance();

    $dependencies = [];

    $params = $constructor->getParameters();
    foreach ($params as $param) {
        // Check for type hints in constructor
        $paramType = $param->getClass();
        if($paramType) {
            // If there are type hints, call this very function
            // again (recursion) in order to fetch dependency
            $dependencies[] = instantiate($paramType->name);
        }
    }

    // Return object (resp. dependency if in recursion loop)
    // while also passing required constructor parameters
    return $reflection->newInstanceArgs($dependencies);
}

$foo = instantiate('foo');
如果打印r($foo),您将看到对象“foo”包含其依赖项

foo Object
(
    [bar] => Bar Object
        (
            [foobar] => foobar Object
                (
                )

        )

)

递归肯定是有用的。但实际上,你为什么不去看看一个容器的源代码,看看它是如何实现的呢?