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

Pimple相关的源码

时间:2023-03-29 18:51:44 PHP

已经对Pimple进行了很好的分析,建议先阅读:Pimple-ASimplePHPDependencyInjectionContainer阅读PHP-Pimple源码笔记(上)阅读PHP-Pimple源码笔记(Part2)下面举例补充说明核心方法:相关类型:service(类似单例):$container['session']=function($c){returnnewSession($c['session_storage']);};工厂服务(多个实例)$container['session']=$container->factory(function($c){returnnewSession($c['session_storage']);});参数(只保存一些变量)$container['cookie_name']='SESSION_ID';受保护的参数(匿名函数会被认为是[1个服务],但是如果你只是想把它作为参数使用,就需要使用这个方法)$container['random_func']=$container->protect(function(){返回随机数();});setassignment相关源码:publicfunctionoffsetSet($id,$value){//如果是frozen,则不能赋值if(isset($this->frozen[$id])){thrownewFrozenServiceException($id);}//保存值$this->values[$id]=$value;//保存在keys$this->keys[$id]=true;}以[1服务]为例,调用offsetSet方法后:$this->values['session']=function($c){returnnewSession($c['session_storage']);};$this->keys['session']=true;使用$session=$container['session'];时,此时调用offsetGet方法:publicfunctionoffsetGet($id){//$this->keys['session']existsif(!isset($this->keys[$id])){thrownewUnknownIdentifierException($id);}if(isset($this->raw[$id])//$this->raw['session'],第一次调用不可用所以为false,重复调用为true||!\is_object($this->values[$id])//所有匿名函数都是对象,所以false对应的情况【3个参数】为真||isset($this->protected[$this->values[$id]])//没有调用protected方法,所以为false,对应情况[4个保护参数]True||!\method_exists($this->values[$id],'__invoke')//所有匿名函数都有__invoke方法,所以为false){//总结一下,如果是第一次调用,就不会执行到这一步。如果与重复调用、参数、受保护方法有关,则执行return$this->values[$id];}//判断是否有多个实例,对应[2个工厂服务],由于我们没有调用工厂方法,所以这一步不会执行if(isset($this->factories[$this->values[$id]])){返回$this->values[$id]($this);}//此时$raw就是函数($c)这个匿名函数$raw=$this->values[$id];//重新赋值$this->values['session'],传入$this输入,相当于函数($this),之所以传入$this是因为匿名函数可能还包含其他服务,//比如上面的$c['session_storage'],$this传入后,相当于$container['session_storage'],这个方法会触发调用offsetGet。$val=$this->values[$id]=$raw($this);//将原来的匿名函数保存到$this->raw中,此时$this->raw['session']有值,重复访问时做以上判断直接返回,相当于单例模式$this->raw[$id]=$raw;//标记冻结,获取后不允许offsetSet或extend$this->frozen[$id]=true;//返回$this->values['session']return$val;}Pimple实现起来比较简单,主要是通过匿名函数实现,不支持像yii2容器这样的普通类构造函数自动解析依赖注入关系等,但是对于仅仅调用单个组件也足够了。