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

  • 相关阅读:
    Linux 服务器注意事项
    维基逃离MySQL 力挺开源数据库 MariaDB
    服务器性能优化
    1 Nginx + 12 Tomcat +2DB 实现2个程序负载均衡
    服务器虚拟化技术 对比简介
    vSphere虚拟系统 添加虚拟服务器
    IIS停止服务 报错Connections_Refused
    windows服务器 IIS FTP服务
    tomcat solr服务无法搜索中文
    查看php相关信息
  • 原文地址:https://www.cnblogs.com/lalalagq/p/9964453.html
Copyright © 2011-2022 走看看