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

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

  • 相关阅读:
    前端与算法 leetcode 344. 反转字符串
    JavaScript闭包使用姿势指南
    前端与算法 leetcode 48. 旋转图像
    前端与算法 leetcode 36. 有效的数独
    前端与算法 leetcode 1. 两数之和
    前端与算法 leetcode 283. 移动零
    前端与编译原理 用js去运行js代码 js2run
    前端与算法 leetcode 66. 加一
    前端与算法 leetcode 350. 两个数组的交集 II
    前端与算法 leetcode 26. 删除排序数组中的重复项
  • 原文地址:https://www.cnblogs.com/lalalagq/p/9964453.html
Copyright © 2011-2022 走看看