Pimple相关的源码

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
icoFoam 求解器名称 |-createFields.H 场变量的声明和初始化 ————————————————————————————————————————————— Info<< "Reading transportProperties\n" << endl; //屏幕提示读入参数控制文件,等价于 C++中std::cout //声明属性字典类对象,该对象由 constant 文件夹下的“transportProperties”初始化创建。 IOdictionary transportProperties ( IOobject //其实IOobject,顾名思义就是输入输出对象,它完成的是一个桥梁的作用,即连接要构造的类及硬盘中的相应文件。这可以通过其成员函数objectStream()了解到,当完成了“搭桥”之后,便可通过这一成员函数返回硬盘文件对应的输入流,从而从输入流中读入将要构造的类的相关信息// ( "transportProperties", // 文件名称 runTime.constant(), // 文件位置,case/constant mesh, // 网格对象 IOobject::MUST_READ_IF_MODIFIED, //如果更改,必须读入 IOobject::NO_WRITE // 不对该文件进行写操作 ) ); //字典查询黏性,以便初始化带有单位的标量 dimensionedScalar nu ( transportProperties.lookup("nu") ); //屏幕提示创建压力场 Info<< "Reading field p\n" << endl; //创建压力场 volScalarField p //声明一个带单位的标量场,网格中心存储变量。 ( IOobject // IOobject主要从事输入输出控制 ( "p", // 压力场初始文件名称 runTime.timeName(), // 文件位置,由case中的system/controlDict中的startTime控制 //

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值