laravel的 容器container(ioc)

来源:互联网 发布:winpe装linux 编辑:程序博客网 时间:2024/06/04 18:51
//ioc//交通工具interface Visit{    public function go();}class Leg implements Visit{    public function go(){        echo 'legs';    }}class Car implements Visit{    public function go(){        echo 'car';    }}class Train implements Visit{    public function go(){        echo '火车';    }}//旅游者类使用的佳通工具ioc容器class Container{    public $binding = [];    public function bind($abstract, $concrete = null, $shared = false ){        if(!$concrete instanceof Closure){            //如果产生的不是闭包函数,则产生默认的闭包函数            //$app->bind('Visit','Train');            $concrete = $this->getClosure($abstract, $concrete);        }        /*         *         * 将回调 $concrete 闭包绑定到 $this->binding[$abstract]         * */        $this->binding[$abstract] = compact('concrete','shared');    }    //默认生成实例的回调函数    public function getClosure($abstract, $concrete){        //生成实例的回调函数,$c 一般为ioc容器对象 在调用回调生成实例时调用        //buid 函数中 $concrete($this)        return function ($c) use ($abstract, $concrete){            $method = ($abstract === $concrete)?'build':'make';            //调用的容器的build或者是make方法生成实例            return $c->$method($concrete);        };    }    //生成实例对象 首先解决接口和要实例化类之间的依赖关系    public function make($abstract){        //获取绑定的闭包函数        $concrete = $this->getConcrete($abstract);        //判断绑定的是不是闭包如果不是判断参数和获取的闭包是不是同一个,如果是同一个则表示需要实例化此对象        if($this->isBuildable($concrete, $abstract)){            $obj = $this->build($concrete);        } else {            $obj = $this->make($concrete);        }        return $obj;    }    //判断绑定的回调是否和传进来的是否相同    public function isBuildable($concrete, $abstract){        return $concrete === $abstract || $concrete instanceof Closure;    }    //获取绑定的闭包函数,如果没有绑定则返回参数    public function getConcrete($abstract){        if( !isset($this->binding[$abstract])){            return $abstract;        }        return $this->binding[$abstract]['concrete'];    }    //实例化对象    public function build($concrete){        if($concrete instanceof Closure){            //返回执行回调并把当前容器穿进去            return $concrete($this);        }        //开始实例化此对象        $reflector = new ReflectionClass($concrete);        //如果此对象不能实例化报错        if(!$reflector->isInstantiable()){            echo 'target $concrete is not instantiable';        }        //获取对象的构造函数        $constructor = $reflector->getConstructor();        //如果对象没有构造函数则返回此对象        if(is_null($constructor)){            return new $concrete;        }        //获取构造函数的参数此类是 reflectionParameter对象构成的数组        $dependencies = $constructor->getParameters();        //获取依赖的类        $instances = $this->getDependencies($dependencies);        //创建一个新的类实例并把 获取到的依赖类的实例穿进去        return $reflector->newInstanceArgs($instances);    }    //通过反射机制通过实例化对象的依赖    public function getDependencies($parameters){        $dependencies = [];        //$parameters  ReflectionParameter类组成的数组        foreach($parameters as $parameter){            //获取参数类型(类就是一种类型);            $dependency = $parameter->getClass();            if(is_null($dependency)){                $dependencies[] = null;            }else {                //获取已经注册的工具类实例                $dependencies[] = $this->resolveClass($parameter);            }        }        return (array) $dependencies;    }    public function resolveClass(ReflectionParameter $parameter){        //获取参数类名        return $this->make($parameter->getClass()->name);    }}class Traveller{    public $trafficTool;    public function __construct(Visit $trafficTool)    {        $this->trafficTool = $trafficTool;    }    public function visitTibet(){        $this->trafficTool->go();    }}
$app = new Container();//完成容器的填充//$app->bind('Visit',function(){//    return new Train();//});$app->bind('Visit','Train');//$app->bind('Visit','Car');$app->bind('traveller','Traveller');//print_r($app->binding);//print_r($app->binding);//通过容器实现依赖注入,完成类的实例化$tra = $app->make('traveller');$tra->visitTibet();
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 老板跑了财务负责人怎么办 在南京加入嘀嘀代驾怎么办 苹果盗刷支付宝怎么办 街电支付宝掉了怎么办 转转上号器没有苹果版的怎么办 安卓6不支持的应用怎么办 银行卡被存款机吞了怎么办 去银行卡存款机器故障怎么办 银行卡存款没有存进去怎么办 被黑网站黑钱了怎么办 饿了吗账户异常怎么办 单位里有人整你怎么办 乌鲁木齐信息采集结束后怎么办 头发很长时间不长怎么办啊 打嘟噜时间不长怎么办 阴茎勃起的时间不长怎么办 睡觉的时间不长怎么办 每次锻炼时间不长怎么办 微信好友不知道是谁怎么办 就一个软件闪退怎么办 葫芦侠修改闪退怎么办 戴尔游匣磁盘占用100怎么办 步步高家教机扫描笔不亮怎么办 社保卡手机号换了怎么办 香港公司进出口没有申报怎么办 智能电视右上角网络未连接怎么办 电子秤按键板不好用怎么办失灵 桑塔纳车钥匙锁车里了怎么办 舌头上有锯齿印怎么办 夏天有脚气脚臭怎么办 xp分辨率太高黑屏怎么办 农村淘宝标识类目没了怎么办 被投诉到食品监督局怎么办 被客户315投诉了怎么办 给人打不接受调解怎么办 失业证年审忘了怎么办 工商年检过期4天怎么办 个体营业执照年审过期了怎么办 企业年报密码忘了怎么办 税务年报报错了怎么办 工商证过期5年怎么办