当前位置: 首页 > 后端技术 > PHP

在实现一个简单的di容器

时间:2023-03-29 15:57:39 PHP

之前,看了很多框架,laravel,thinkphp,yii等等。基本上都是用容器。对我来说,虽然我明白laravel是怎么写的,但是如果我自己不去尝试,我还是觉得不会。下面的代码是我实现的一个简单的容器。很多地方不是很好,但是应该够用了。instanceprivate$binds=[]的映射;公共静态$实例=空;/***单一案例*/publicstaticfunctiongetInstance(){if(static::$instance==null){static::$instance=newstatic();返回静态::$实例;}返回静态::$实例;}/***原来是受laravel的影响,所以写了一个bind函数,*看了laravel的容器实现,印象中$concrete和$abstract来回切换。*下面的代码有点像thinkphp中的实现,所以比较容易理解*/publicstaticfunctionbind($name,$class=null){if($classinstanceofClosure){static::getInstance()->绑定[$名称]=$类;}elseif(is_object($class)){static::getInstance()->binds[$name]=$class;}else{//这里开始做数组,laravel好像是make和build分开的。static::getInstance()->make($name);}}/***核心是make方法*/publicstaticfunctionget($name){returnstatic::getInstance()->make($name);}/***核心make方法*/publicfunctionmake($name){try{//根据类名检查$this->binds实例是否已经存在,如果存在则直接返回if(array_key_exists($名称,$this->binds)){返回$this->binds[$name];}//根据类名获取其反射类$reflectClass=newReflectionClass($name);//使用反射类$constructor=$reflectClass->getConstructor();//如果没有构造函数,直接实例化$params=[];if(!is_null($constructor)){//获取构造函数中的方法$constructorParams=$constructor->getParameters();//var_dump($constructorParams);//保存构造函数的参数foreach($constructorParamsas$constructorParam){//这个地方主要是判断参数是否是类,如果是则递归构造,或者干脆加到$this->paramsif(!is_null($constructorParam->getType())){$params[]=$this->make($constructorParam->name,$constructorParam->name);}else{$params[]=$constructorParam->name;}}}//在这里构造一个实例$class=$reflectClass->newInstanceArgs($params);//绑定$this->binds[$name]=$class;返回$类;}catch(ReflectionException$e){echo$e->getMessage();}}privatefunction__construct(){}privatefunction__clone(){}}?>下面是我的测试文件,name;}publicfunctionsayDI2Name(DI2$di2){//如果这样写的,di2方法会先从前面的字符串打印出来//echo"formTestsaydi2name:".$di2->sayName();echo"formTestsaydi2name:";echo$di2->sayName();}}类DI{private$name="DI";公共函数__construct(DI2$di2){}公共函数sayName(){echo$this->name;}}类DI2{私有$name="DI2";公共函数__construct(){}公共函数sayName(){echo$this->name;}}类DI3{私有$name="DI3";公共函数__construct(){}公共函数sayName(){echo$this->name;}}类DI4{private$name="DI4";公共函数__construct(){}公共函数sayName(){echo$this->name;}}//要不要无所谓了//Container::bind('test','测试');$test=Container::get('test');$test->sayName();echo"\n";$test->sayDI2Name(newDI2());echo"\n";$di=Container::get('di');$di->sayName();echo"\n";$di2=Container::get('di2');$di2->sayName();echo"\n";$di3=newDI3();Container::get('di3',$di3)->sayName();echo"\n";$di4=function(){returnnewDI4();};Container::get('di4',$di4)->sayName();echo"\n";?>最后的结果如下