已经有了非常好的Pimple的相关解析,建议先看下:
Pimple - 一个简单的 PHP 依赖注入容器
读 PHP - Pimple 源码笔记(上)
读 PHP - Pimple 源码笔记(下)

这里通过例子补充下核心方法的说明:
相关的类型:

  1. 服务(类似单例):


    $container['session'] = function ($c) {
    return new Session($c['session_storage']);
    };
  2. 工厂服务(多个实例)


    $container['session'] = $container->factory(function ($c) {
    return new Session($c['session_storage']);
    });
  3. 参数(仅仅是保存一些变量)


    $container['cookie_name'] = 'SESSION_ID';
  4. 保护参数(匿名函数都会被认为【1服务】,但是如果仅仅是想作为一个参数,则需要用此方法)


    $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->values['session'] = function ($c) {
return new Session($c['session_storage']);
};
$this->keys['session'] = true;

使用时$session=$container['session'];,此时调用offsetGet方法:


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容器那样支持普通类的构造函数自动解析依赖注入关系等,但是对于仅仅是调用各个组件来说也足够用了。

原文地址:https://segmentfault.com/a/1190000016747497

最新文章

  1. x01.TestViewContent: 插件测试
  2. C#把 DataTable转换为Model实体
  3. 一个windows下的ddos样本
  4. CoreData教程
  5. ASP.NET MVC 了解FileResult的本质
  6. keyCode,charCode,which
  7. Objective-C运行时编程 - 实现自动化description方法的思路及代码示例
  8. Linux: Bash基本命令
  9. JavaScript正则表达式之分组匹配 / 反向引用
  10. Spring配置补充
  11. 【SPOJ】Distinct Substrings(后缀自动机)
  12. django的models模块查询方法
  13. 基于TCP 协议的RPC
  14. 安全相关及HttpClient
  15. xtrabackup备份MySQL报错:InnoDB: Error number 24 means 'Too many open files'
  16. Oracle EBS compile PLD PLL files.
  17. Linux操作环境下配置MMIX环境
  18. 266B
  19. [Python] 震惊, 我居然用Python干这种事ꈍ .̮ ꈍ
  20. [SHOI2012]随机树[期望dp]

热门文章

  1. laravel报错:MassAssignmentException
  2. 自动合法打印VitalSource Bookshelf中的电子书
  3. 2019-02-25 SQL:cast(itemvalue as decimal(19,4))
  4. C# .net IDE Rider入门
  5. 在Windows系统下搭建Redis集群
  6. mysql字符集修改(ubuntu)
  7. ftp for linux 配置
  8. 中科燕园arcgis外包案例之12---供水供热管线GIS系统
  9. C++11新特性应用--实现延时求值(std::function和std::bind)
  10. HDU 3966 Aragorn's Story 树链剖分+BIT区间修改/单点询问