php依赖注入控制 反转 ioc container

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,其实后面将这些类全部做一个接口类的继承,引用类型全部换成接口类型就更优雅了,面对接口编程。希望以上可以帮到大家,嗷嗷嗷~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值