{public functiondoSomething()
{echo __METHOD__, ‘我是周伯通C|‘;
}
}classB
{private $c;public function __construct(C $c)
{$this->c = $c;
}public functiondoSomething()
{$this->c->doSomething();echo __METHOD__, ‘我是周伯通B|‘;
}
}classA
{private $b;public function __construct(B $b)
{$this->b = $b;
}public functiondoSomething()
{$this->b->doSomething();echo __METHOD__, ‘我是周伯通A|‘;;
}
}classContainer
{private $s = array();public function __set($k, $c)
{$this->s[$k] = $c;
}public function __get($k)
{//return $this->s[$k]($this);
return $this->build($this->s[$k]);
}/**
* 自动绑定(Autowiring)自动解析(Automatic Resolution)
*
* @param string $className
* @return object
* @throws Exception*/
public function build($className)
{//如果是匿名函数(Anonymous functions),也叫闭包函数(closures)
if ($classNameinstanceof Closure) {//执行闭包函数,并将结果
return $className($this);
}/** @var ReflectionClass $reflector*/
$reflector = new ReflectionClass($className);//检查类是否可实例化, 排除抽象类abstract和对象接口interface
if (!$reflector->isInstantiable()) {throw new Exception("Can‘t instantiate this.");
}/** @var ReflectionMethod $constructor 获取类的构造函数*/
$constructor = $reflector->getConstructor();//若无构造函数,直接实例化并返回
if (is_null($constructor)) {return new $className;
}//取构造函数参数,通过 ReflectionParameter 数组返回参数列表
$parameters = $constructor->getParameters();//递归解析构造函数的参数
$dependencies = $this->getDependencies($parameters);//创建一个类的新实例,给出的参数将传递到类的构造函数。
return $reflector->newInstanceArgs($dependencies);
}/**
* @param array $parameters
* @return array
* @throws Exception*/
public function getDependencies($parameters)
{$dependencies =[];/** @var ReflectionParameter $parameter*/
foreach ($parameters as $parameter) {/** @var ReflectionClass $dependency*/
$dependency = $parameter->getClass();if (is_null($dependency)) {//是变量,有默认值则设置默认值
$dependencies[] = $this->resolveNonClass($parameter);
}else{//是一个类,递归解析
$dependencies[] = $this->build($dependency->name);
}
}return $dependencies;
}/**
* @param ReflectionParameter $parameter
* @return mixed
* @throws Exception*/
public function resolveNonClass($parameter)
{//有默认值则返回默认值
if ($parameter->isDefaultValueAvailable()) {return $parameter->getDefaultValue();
}throw new Exception(‘I have no idea what to do here.‘);
}
}//----
$class = newContainer();$class->b = ‘B‘;$class->a = function ($class) {return new A($class->b);
};//从容器中取得A
$model = $class->a;$model->doSomething();$di = newContainer();$di->php7 = ‘A‘;/** @var A $php7*/
$foo = $di->php7;var_dump($foo);$foo->doSomething(); //C::doSomething我是周伯通C|B::doSomething我是周伯通B|A::doSomething我是周伯通A|object(A)#10 (1) { ["b":"A":private]=> object(B)#14 (1) { ["c":"B":private]=> object(C)#16 (0) { } } } C::doSomething我是周伯通C|B::doSomething我是周伯通B|A::doSomething我是周伯通A|
?>