已经有了非常好的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

Pimple相关的源码的更多相关文章

  1. List 接口以及实现类和相关类源码分析

    List 接口以及实现类和相关类源码分析 List接口分析 接口描述 用户可以对列表进行随机的读取(get),插入(add),删除(remove),修改(set),也可批量增加(addAll),删除( ...

  2. fork()相关的源码解析

    fork()的真正执行采用的是do_fork()函数,所以下文将从do_fork()函数对fork()进行源码解析.下图是do_fork()的源码函数设计: 从上图我们可以看到do_fork()涉及到 ...

  3. 分享一些阅读Java相关框架源码的经验

    昨天和部分网友进行了线上的交流,交流中有不少网友提到阅读源码比较难,不知道怎么上手.胖哥分享了一些个人经验,这里总结一下. 阅读源码实际上是Debug源码 其实所谓的阅读源码并不是单纯的阅读,而是调试 ...

  4. Cocos2d-X3.0 刨根问底(八)----- 场景(Scene)、层(Layer)相关源码分析

    本章节我们重点分析Cocos2d-x3.0与 场景.层相关的源码.这部分源码集中在 libcocos2d –> layers_scenes_transitions_nodes目录下面 我先发个截 ...

  5. Android AdapterView 源码分析以及其相关回收机制的分析

    忽然,发现,网上的公开资料都是教你怎么继承一个baseadapter,然后重写那几个方法,再调用相关view的 setAdpater()方法, 接着,你的item 就显示在手机屏幕上了.很少有人关注a ...

  6. motan源码分析五:cluster相关

    上一章我们分析了客户端调用服务端相关的源码,但是到了cluster里面的部分我们就没有分析了,本章将深入分析cluster和它的相关支持类. 1.clustersupport的创建过程,上一章的Ref ...

  7. react 中间件相关的一些源码解析

    零.随便说说中间件 在react的使用中,我们可以将数据放到redux,甚至将一些数据相关的业务逻辑放到redux,这样可以简化我们组件,也更方便组件抽离.封装.复用,只是redux不能很好的处理异步 ...

  8. Spring:源码解读Spring IOC原理

    Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. I ...

  9. redis 源码阅读 内部数据结构--字符串

    redis的内部数据结构主要有:字符串,双端链表,字典,跳跃表. 这里主要记录redise字符串的设计.相关的源码位于:src/sds.h 和 src/sds.c.   一 字符串 sds的结构体 s ...

随机推荐

  1. bzoj 3028: 食物 生成函数_麦克劳林展开

    不管怎么求似乎都不太好求,我们试试生成函数.这个东西好神奇.生成函数的精华是两个生成函数相乘,对应 $x^{i}$ 前的系数表示取 $i$ 个时的方案数. 有时候,我们会将函数按等比数列求和公式进行压 ...

  2. AC Codeforces Round #499 (Div. 2) E. Border 扩展欧几里得

    没想出来QAQ....QAQ....QAQ.... 对于一般情况,我们知道 ax+by=gcd(a,b)ax+by=gcd(a,b)ax+by=gcd(a,b) 时方程是一定有解的. 如果改成 ax+ ...

  3. [luogu4259 SCOI2003] 严格N元树 (高精 计数dp)

    题目描述 如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树.如果该树中最底层的节点深度为d(根的深度为0),那么我们称它为一棵深度为d的严格n元树.例如,深度为2的严格2元树有三个, ...

  4. javaScript - 面向对象 - ES5 和 ES6

    javaScript - 面向对象 - ES5 和 ES6 ES5之前用 构造函数 构造函数的特点 就是一个普通函数, 他的函数名要大写.: 带方法的写法: 原型的方式: prototype 为内置的 ...

  5. STM32 使用Cubemx 建一个USB(HID)设备下位机,实现数据收发

    这里我主要说一下如何做一个USB下位机,这里主要分3部分:1.建立工程:2.添加报文描述符:3.数据的传输.这里就不讲USB的理论知识了,有想要了解的自行百度一下就可以了. 建立工程:工程建立参考:h ...

  6. React 中的 AJAX 请求:获取数据的方法

    React 中的 AJAX 请求:获取数据的方法 React 只是使用 props 和 state 两处的数据进行组件渲染. 因此,想要使用来自服务端的数据,必须将数据放入组件的 props 或 st ...

  7. React入门基础

    1-react概念: React是一个用于构建用户界面的JavaScript库.React主要用于构建UI,很多人认为React是MVC中的V(视图).React起源于Facebook的内部项目.Re ...

  8. cogs 2060. 除法表达式

    2060. 除法表达式 ★★   输入文件:baoquansl.in   输出文件:baoquansl.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] 经过无尽的蘑菇和 ...

  9. java.util.UnknownFormatConversionException: Conversion = ''';

    今天在测试一个新的项目,在执行sql查询报表的时候.由于我的sql中带有%,导致在输出日志时报错“java.util.UnknownFormatConversionException: Convers ...

  10. maven打包可运行的jar包(包含依赖工程)

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...