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

Phalcon2.0.9源码分析

时间:2023-03-29 13:54:53 PHP

PhalconDI源码分析interfaceDiInterfaceextends\\ArrayAccess{}PHPArrayAccess接口因此,在Di中,必须实现以下接口方法:其中,继承自\ArrayAccess预定义接口:offsetExists():判断下标是否存在。offsetGet():获取下标$offset的值。offsetSet():设置下标偏移值时调用。offsetUnset():取消下标偏移。其中,继承自DiInterface接口:set(string!name,definition,booleanshared=false)->:注册服务时,会调用该方法,name表示服务名称,definition表示如何定义实现,shared表示是否共享。setShared(string!name,definition)->:表示向服务容器注册一个始终共享的服务。remove(string!name):从服务容器中删除一个服务。attempt(string!name,definition,booleanshared=false)->:在服务容器中注册一个之前没有注册过的服务才能成功。get(string!name,parameters=null):解析服务实例。getShared(string!name,parameters=null):解析获取共享实例。setRaw(string!name,rawDefinition)->:使用原来的\Phalcon\Di\Service来定义一个服务,即直接给一个ServiceInterface接口实现类的实例。/***使用原始Phalcon\Di\Service定义设置服务*/publicfunctionsetRaw(string!name,rawDefinition)->{letthis->_services[name]=rawDefinition;returnrawDefinition;}getRaw(string!name):getService(string!name)->:返回对应name的\Phalcon\Di\Service实例。has(string!name)->boolean:检查容器是否包含名称的实例。wasFreshInstance()->boolean:检查通过getShared共享的最后一个服务是否生成了实例或现有实例。getServices():从DI中获取实例。setDefault(dependencyInjector):设置默认使用的di容器。getDefault()->:获取默认di容器reset():设置默认di容器为null。di容器类的方法分析:1.构造方法__construct():/***Phalcon\\Diconstructor*/publicfunction__construct(){vardi;让di=self::_default;如果!di{让自己::_default=this;}}在构造函数中,会先判断是否设置了默认di容器,如果没有,则使用当前di类作为默认容器。2.set()方法:/***在服务容器中注册一个服务*/publicfunctionset(string!name,vardefinition,booleanshared=false)->{varservice;letservice=newService(name,definition,shared),this->_services[name]=service;returnservice;}该方法主要用于向服务容器中注入一个服务,可以设置是否共享。设置服务时,实际上是实例化一个\Phalcon\Di\Service类,将Service实例设置为di->_services属性的一项。3、setShared()方法:与set()方法不同,setShared()方法注入的服务默认是共享的(letservice=newService(name,definition,true))。4.remove()方法:从当前di的_services中移除服务,移除共享实例属性。5、attempt()方法:/***该方法注入时会判断要注入的服务是否已经存在。如果已经存在,则不注入(set和setShared都会被覆盖)*/publicfunctionattempt(string!name,definition,booleanshared=false)->|布尔值{var服务;if!issetthis->_services[name]{letservice=newService(name,definition,shared),this->_services[name]=service;退货服务;}returnfalse;}6.setRaw()方法:/***使用该方法注入时,需要注入一个Phalcon\\Di\\Service接口的实例(不再实例Service,直接使用服务接口实例)*/publicfunctionsetRaw(string!name,rawDefinition)->{letthis->_services[name]=rawDefinition;returnrawDefinition;}7,getRaw()方法:/***返回一个服务定义*/publicfunctiongetRaw(string!name)->var{varservice;如果获取服务,this->_services[name]{returnservice->getDefinition();}thrownewException("Service'".name."'在依赖注入容器中找不到");}8.getService()方法:返回一个服务的Service实例9.get()方法:解析并返回一个服务实例。/***解析并返回服务实例*/publicfunctionget(string!name,parameters=null)->var{varservice,instance,reflection,eventsManager;让eventsManager=this->_eventsManager;//indi:beforeServiceResolve事件会在解析服务之前执行);}//判断服务是否已经注册iffetchservice,this->_services[name]{/***如果已经注册,直接调用Service->resolve()方法解析获取实例*/让instance=service->resolve(parameters,this);}else{/***当没有注册到Service中时,直接调用get服务时,di本身也可以作为解析器来解析获取实例。*/if!class_exists(name){thrownewException("Service'".name."'在依赖注入容器中找不到");}//判断参数是否为数组iftypeofparameters=="array"{//当参数为数组且不为空时,通过反射newInstanceArgs()方法获取实例ifcount(parameters){ifis_php_version("5.6"){letreflection=new\ReflectionClass(name),instance=reflection->newInstanceArgs(parameters);}else{letinstance=create_instance_params(name,parameters);}}else{//当参数为空时,反射的newInstance()方法返回一个实例ifis_php_version("5.6"){letreflection=new\ReflectionClass(name),instance=reflection->newInstance();}else{letinstance=create_instance(name);}}}else{如果is_php_version("5.6"){letreflection=new\ReflectionClass(name),instance=reflection->newInstance();}else{letinstance=create_instance(name);}}}/***如果解析的服务实例本身实现了IfInjectionAwareInterface接口(即,如果它也是一个容器),设置用于该实例的DI容器*/iftypeofinstance=="object"{ifinstanceofInjectionAwareInterface{instance->setDI(this);}}//解析完成后,执行di:afterServiceResolveevent":instance]);}returninstance;}10.getShared()方法:/***获取共享服务*/publicfunctiongetShared(string!name,parameters=null){varinstance;/***如果有一个实例化的服务,然后直接返回*/iffetchinstance,this->_sharedInstances[name]{让这个->_freshInstance=false;}else{/***如果没有实例化服务,解析并返回服务*/letinstance=this->get(name,parameters);/***将实例化的服务放入服务池*/letthis->_sharedInstances[name]=instance,this->_freshInstance=true;}returninstance;}11.has()方法:DI容器的标准方法12.wasFreshInstance()方法:判断新获取的实例是直接从服务池中获取还是已经存在的现成实例(参考getShared()方法)。13、getServices()方法:从容器DI中获取所有注入的服务。14、offsetExists()方法:由于继承自\ArrayAccess接口,di容器支持数组访问,该方法用于判断某个服务是否存在。15、offsetSet()方法:di支持通过数组设置服务,例如:$this['a']='b';16、offsetGet()方法:通过数组获取服务,例如:$a=$this['a'];17.offsetUnset()方法:直接在代码中返回false,目前di不支持unset($this['a'])方法移除注入的服务。18.__call()方法:/***支持通过getA或setA等方法获取或注入服务。*@paramstringmethod*@paramarrayarguments*/publicfunction__call(string!method,arguments=null)->var|null{varinstance,possibleService,services,definition;/***get开头表示获取*/ifstarts_with(method,"get"){letservices=this->_services,possibleService=lcfirst(substr(method,3));ifissetservices[possibleService]{ifcount(arguments){letinstance=this->get(possibleService,arguments);}else{letinstance=this->get(possibleService);}返回实例;}}/***设置注入服务*/ifstarts_with(method,"set"){iffetchdefinition,arguments[0]{this->set(lcfirst(substr(method,3)),definition);返回空值;}}/***当服务不存在时,返回异常*/thrownewException("Calltoundefinedmethodorservice'".method."'");}19.setDefault()方法:设置di默认使用的容器。具体使用请参考构造函数。20.getDefault()方法:获取di容器。21.reset():将当前使用的di容器默认设置为null。/Phalcon/Di/Service类分析实例:摘要注入方式1.setShared():默认注入的是共享服务。2.set():允许定义当前注入的服务是否可共享。3.attempt():允许注入尚未注入的服务,自定义是否可以共享。4.setRaw():直接注入一个服务实例。5.offsetSet():以数组的形式注入服务,例如:\$this['app']=$this。6.__call():魔术方法注入,例如:setA()方法注入。获取方式1.get():获取一个服务实例。2.getShared():获取可共享的服务。3、offsetGet():通过数组获取,例如:\$app=$this['app']。4.__call():魔术方法获取,例如:getA()方法。