di容器就是指当你需要一个资源的时候直接找容器要,容器接管了主导权,这也就是相对平常我们需要正向去主动new一个对象,现在就是被di容器“反转控制”了,我们只能去求这它要,从而被动接受了,其中我需要的对象也要好资源也罢,它们的依赖关系咱都别管容器来搞定,这就是ioc和di。
我们来看几个例子
class phone
{
public $obj;
public function __construct()
{
$this->obj = new usb();//注意这里主动去new了需要的对象
}
public function act()
{
$this->obj->dosth();
}
}
class usb
{
public function dosth(){
echo 1;
}
}
$phone = new phone();
$phone->act();
这里是在类里面去new的,也就是主动去要的,我们接下来要剥夺它的权利,不给它new,看下面代码
class phone
{
public $obj;
public function __construct($obj)
{
$this->obj = $obj;//注意这里剥夺权利了
}
public function act()
{
$this->obj->dosth();
}
}
class usb
{
public function dosth(){
echo 1;
}
}
$usb=new usb;
$phone = new phone($usb);
$phone->act();
但是觉得这个好像只是变成了传参而已,对就是这个思想,但是不够优雅,没有用到容器
class phone
{
public $obj;
public function __construct($obj)
{
$this->obj = $obj;//注意这里主动去new了需要的对象
}
public function act()
{
$this->obj->dosth();
}
}
class usb
{
public function dosth(){
echo 1;
}
}
class container
{
public $objs = [];//存储资源
public function bind($class, Closure $closure_obj)
{
$this->objs[$class] = $closure_obj;
}
public function make($class)
{
$new = $this->objs[$class];
return $new();
}
}
$container=new container;
$container->bind('usb',function(){
return new usb;
});
$phone = new phone($container->make('usb'));
$phone->act();
但是我们的phone还是new出来的,这样也不太优雅,接着改造加入反射,嗷嗷嗷~~~
class phone
{
public $obj;
public function __construct( usb $obj)
{
$this->obj = $obj;//注意这里主动去new了需要的对象
}
public function act()
{
$this->obj->dosth();
}
}
class usb
{
public function dosth(){
echo 1;
}
}
class container
{
public $objs = [];//存储资源
public function bind($class, $closure_obj)
{
if(! $closure_obj instanceof Closure){
$this->objs[$class] = function ()use($closure_obj){
return $this->ref($closure_obj);
};
}else{
$this->objs[$class] = $closure_obj;
}
}
public function make($class)
{
if(isset($this->objs[$class])){
$new= $this->objs[$class];
}else{
$new=$this->ref($class);
}
return $new();
}
public function ref($class,$params=[]){
$ref=new ReflectionClass($class);
if($ref->isInstantiable()){
$constructor =$ref->getConstructor();
if(!is_null($constructor)){
$pars = $constructor->getParameters();
if(empty($pars)){
return new $class;
}else{
foreach ($pars as $par) {
$dependencyClass = $par->getClass();
if (is_null($dependencyClass)) {
$dependencies[] = NULL;
} else {
// 类存在创建类实例
$dependencies[] = $this->make($par->getClass()->name);
}
}
return $ref->newInstanceArgs($dependencies);
}
}else{
return new $class;
}
}
return null;
}
}
$container=new container;
$container->bind('usb',function(){
return new usb;
});
$container->bind('phone','phone');
$phone = $container->make('phone');
$phone->act();
这样全程只有在容器里有new了,哪里用了new哪里就有主导权了,等于权利拿到手了,当然还有闭包函数里有new,其实后面将这些类全部做一个接口类的继承,引用类型全部换成接口类型就更优雅了,面对接口编程。希望以上可以帮到大家,嗷嗷嗷~~~