rrylee
9/21/2016 - 2:24 PM

container-demo.php

<?php

class App
{
    public function build($className)
    {
        if ($className instanceof Closure) {
            return $className();
        }
        // 创建反射类
        $reflector = new ReflectionClass($className);
        // 不能实例化,抛异常
        if (! $reflector->isInstantiable()) {
            $message = "Target [$className] is not instantiable.";

            throw new Exception($message);
        }
        // 创建构造器
        $constructor = $reflector->getConstructor();
        // 没有构造函数
        if ($constructor === null) {
            return new $className;
        }
        // 获取构造函数参数
        $dependencies = $constructor->getParameters();
        // 获取依赖实例对象
        $instances = $this->getDependencies($dependencies);
        // 实例化对象
        return $reflector->newInstanceArgs($instances);
    }

    protected function getDependencies($parameters)
    {
        $dependencies = [];

        foreach ($parameters as $parameter) {
            $dependency = $parameter->getClass();

            if ($dependency === null) {
                $dependencies[] = $this->resolveNonClass($parameter);
            } else {
                $dependencies[] = $this->build($dependency->name);
            }
        }

        return (array) $dependencies;
    }

    protected function resolveNonClass($parameter)
    {
        if(! $parameter->isDefaultValueAvailable()) {
            $message = "Unresolvable dependency resolving [$parameter] in class {$parameter->getDeclaringClass()->getName()}";

            throw new Exception($message);
        }

        return $parameter->getDefaultValue();
    }
}