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

tp5源码分析容器

时间:2023-03-29 17:25:32 PHP

的含义用于更方便的管理类依赖和运行依赖注入前置条件熟悉单例模式,注册树模式熟悉反射机制理解依赖注入和控制反转简单过一下概念单例模式:一个类最多只允许一个实例注册模式:有点类似于单例模式,创建一个实例放到盒子里,下次需要的时候根据ID直接从盒子里取当然,它可以创建多实例反射机制:提供对类、接口、函数、方法和扩展进行逆向工程的能力。主要依赖几个类ReflectionClass和ReflectionMethod。这个非常重要。没有它,就没有后续的依赖注入dependencyinjectionandcontrolInversion:降低应用层和业务层的耦合度推荐阅读理解DependencyInjectionandInversionofControlCodeimplementation如果你明白前置条件说的是什么,容器就会容易明白。看入口文件index.php中的这一行代码Container::get('app')->run()->send();首先注意前面的Container::get('app'),这里使用的是容器。从容器中获取app对象,输入get()/***获取容器中的对象实例*@accesspublic*@paramstring$抽象类名或logo*@paramarray|true$vars变量*@parambool$newInstance是否每次都创建一个新实例*@returnobject*/publicstaticfunctionget($abstract,$vars=[],$newInstance=false){returnstatic::getInstance()->make($abstract,$vars,$newInstance);}获取容器本身的单例,然后调用make方法进入make()。这一步主要是将标识名映射到类名,比如'app'=>'thinkapp',(这个映射关系在成员方法$bind中),然后调用invokeClass()方法实例化,最后将实例化值放入容器中。/***创建一个类的实例*@accesspublic*@paramstring$抽象类名或标识符*@paramarray|true$vars变量*@parambool$newInstance是否每次都创建一个新实例*@returnobject*/publicfunctionmake($abstract,$vars=[],$newInstance=false){if(true===$vars){//总是创建一个新的实例化对象$newInstance=true;$变量=[];}//第一次没有这个标识名,$abstract='app'$abstract=isset($this->name[$abstract])?$this->名称[$抽象]:$抽象;//不。一旦进入,容器中就没有这个对象的实例了}if(isset($this->bind[$abstract])){//第一个入口,$concrete=App::class,即think\App$concrete=$this->bind[$abstract];if($concreteinstanceofClosure){$object=$this->invokeFuncti上($混凝土,$vars);}else{//添加别名$this->name['app']='think\App';然后再次调用make,$this->make('think\App',[],false)$this->name[$abstract]=$concrete;返回$this->make($concrete,$vars,$newInstance);}}else{//第二次调用直接到这里$object=$this->invokeClass($abstract,$vars);}if(!$newInstance){$this->instances[$abstract]=$object;}返回$对象;}invokeClass()方法是基于反射机制进行类实例化的/***调用反射执行类实例化支持依赖注入*@accesspublic*@paramstring$class类名*@paramarray$vars参数*@returnmixed*/publicfunctioninvokeClass($class,$vars=[]){try{$reflect=newReflectionClass($class);如果($reflect->hasMethod('__make')){$method=newReflectionMethod($class,'__make');如果($方法->是Public()&&$method->isStatic()){$args=$this->bindParams($method,$vars);}返回$method->invokeArgs(null,$args);}}$constructor=$reflect->getConstructor();//判断要实例化的类是否有构造函数,如果有构造函数,是否传递参数,参数是否为对象类型等。$args=$constructor?$this->bindParams($constructor,$vars):[];返回$reflect->newInstanceArgs($args);}catch(ReflectionException$e){thrownewClassNotFoundException('类不存在:'.$class,$class);}}未完待续~~~

最新推荐
猜你喜欢