已经有了很是好的Pimple的相关解析,建议先看下:
Pimple - 一个简单的 PHP 依赖注入容器
读 PHP - Pimple 源码笔记(上)
读 PHP - Pimple 源码笔记(下)segmentfault
这里经过例子补充下核心方法的说明:
相关的类型:yii2
服务(相似单例):cookie
$container['session'] = function ($c) { return new Session($c['session_storage']); };
工厂服务(多个实例)session
$container['session'] = $container->factory(function ($c) { return new Session($c['session_storage']); });
参数(仅仅是保存一些变量)dom
$container['cookie_name'] = 'SESSION_ID';
保护参数(匿名函数都会被认为【1服务】,可是若是仅仅是想做为一个参数,则须要用此方法)yii
$container['random_func'] = $container->protect(function () { return rand(); });
set赋值相关源码:函数
public function offsetSet($id, $value) { //若是是被冻结,则没法赋值 if (isset($this->frozen[$id])) { throw new FrozenServiceException($id); } //存入values $this->values[$id] = $value; //存入keys $this->keys[$id] = true; }
用【1服务】来举例,调用offsetSet方法后:this
$this->values['session'] = function ($c) { return new Session($c['session_storage']); }; $this->keys['session'] = true;
使用时$session=$container['session'];
,此时调用offsetGet方法:code
public function offsetGet($id) { //$this->keys['session']存在 if (!isset($this->keys[$id])) { throw new UnknownIdentifierException($id); } if ( isset($this->raw[$id])//$this->raw['session'],第一次调用是没有的,因此为false,重复调用则为ture || !\is_object($this->values[$id])//全部的匿名函数都是object,因此为false。对应的状况【3参数】时为true || isset($this->protected[$this->values[$id]])//未调用protected方法,因此为false,对应的状况【4保护参数】时为true || !\method_exists($this->values[$id], '__invoke')//全部匿名函数存在__invoke方法,因此为false ) { //综上,若是是第一次调用,不会执行到这一步,若是是重复调用、参数、protected方法相关的,则会执行 return $this->values[$id]; } //断定是否是多个实例,对应【2工厂服务】,因为咱们没有调用factories方法,因此这一步也不会执行 if (isset($this->factories[$this->values[$id]])) { return $this->values[$id]($this); } //此时$raw就是function ($c) 这个匿名函数 $raw = $this->values[$id]; //从新赋值$this->values['session'],将$this传入,至关于function ($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; //标记已冻结,已经get后则不容许offsetSet或者extend了 $this->frozen[$id] = true; //返回$this->values['session'] return $val; }
Pimple实现起来比较简单,主要是经过匿名函数来实现,没有像yii2容器那样支持普通类的构造函数自动解析依赖注入关系等,可是对于仅仅是调用各个组件来讲也足够用了。get