• yii2框架随笔25


    今天来看Container.php,yii2的容器代码。

    <?php
    /**
     * @link http://www.yiiframework.com/
     * @copyright Copyright (c) 2008 Yii Software LLC
     * @license http://www.yiiframework.com/license/
     */
    namespace yiidi;
    use ReflectionClass;
    use yiibaseComponent;
    use yiibaseInvalidConfigException;
    /**
     * Container implements a [dependency injection](http://en.wikipedia.org/wiki/Dependency_injection) container.
     * 实现了依赖注入容器(http://en.wikipedia.org/wiki/dependency_injection)。
     * A dependency injection (DI) container is an object that knows how to instantiate and configure objects and
     * all their dependent objects.
     * 依赖注入(DI)的容器是一个对象,知道如何实例化和配置所有的依赖对象。
     *  For more information about DI, please refer to
     *  有关更多信息,请参阅
     * [Martin Fowler's article](http://martinfowler.com/articles/injection.html).
     *
     * Container supports constructor injection as well as property injection.
     * 容器支持构造函数注入以及属性注入。
     * To use Container, you first need to set up the class dependencies by calling [[set()]].
     * 使用的容器,你首先需要设置类的依赖关系,通过调用[[set()]]方法。
     * You then call [[get()]] to create a new class object.
     * 然后你可以调用[[get()]]方法创建一个新的类的对象。
     * Container will automatically instantiate
     * dependent objects, inject them into the object being created, configure and finally return the newly created object.
     * 容器会自动实例化依赖对象,将它们注入到正在创建的对象中,配置并最终返回新创建的对象。
    
     * @property array $definitions The list of the object definitions or the loaded shared objects (type or ID =>
     * definition or instance). This property is read-only.
     *
     * @author Qiang Xue <qiang.xue@gmail.com>
     * @since 2.0
     */
    class Container extends Component
    {
        /**
         * @var array singleton objects indexed by their types
         * 用于保存单例Singleton对象,以对象类型为键
         */
        private $_singletons = [];
        /**
         * @var array object definitions indexed by their types
         * 用于保存依赖的定义,以对象类型为键
         */
        private $_definitions = [];
        /**
         * @var array constructor parameters indexed by object types
         * 用于保存构造函数的参数,以对象类型为键
         */
        private $_params = [];
        /**
         * @var array cached ReflectionClass objects indexed by class/interface names
         * 用于缓存ReflectionClass对象,以类名或接口名为键
         */
        private $_reflections = [];
        /**
         * @var array cached dependencies indexed by class/interface names. Each class name
         * is associated with a list of constructor parameter types or default values.
         * 用于缓存依赖信息,以类名或接口名为键
         */
        private $_dependencies = [];
        /**
         * Returns an instance of the requested class.
         * 返回所请求的类的实例。
         * You may provide constructor parameters (`$params`) and object configurations (`$config`)
         * that will be used during the creation of the instance.
         * 你可以提供构造函数参数(` $params `)和对象的配置(`$config`),在创建实例时使用。
    
         * Note that if the class is declared to be singleton by calling [[setSingleton()]],
         * 注意,如果类声明为单称[[setsingleton()]],
         * the same instance of the class will be returned each time this method is called.
         * 每次调用该方法时,该类的同一实例将被返回。
         * In this case, the constructor parameters and object configurations will be used
         * only if the class is instantiated the first time.
         * 在这种情况下,只有当类被实例化的第一时间,将使用构造函数参数和对象配置.
         * @param string $class the class name or an alias name (e.g. `foo`) that was previously registered via [[set()]]
         * or [[setSingleton()]].
         * @param array $params a list of constructor parameter values. The parameters should be provided in the order
         * they appear in the constructor declaration. If you want to skip some parameters, you should index the remaining
         * ones with the integers that represent their positions in the constructor parameter list.
         * @param array $config a list of name-value pairs that will be used to initialize the object properties.
         * @return object an instance of the requested class.
         * @throws InvalidConfigException if the class cannot be recognized or correspond to an invalid definition
         */
        public function get($class, $params = [], $config = [])
        {
            if (isset($this->_singletons[$class])) {
                // singleton
                // 如果Singleton对象的数组中有,就直接返回
                return $this->_singletons[$class];
            } elseif (!isset($this->_definitions[$class])) {
                // 如果定义的数组中没有,就去构建它
                return $this->build($class, $params, $config);
            }
            $definition = $this->_definitions[$class];
            if (is_callable($definition, true)) {
                // 如果$definition是callable,就先将参数合并,再将其中的Instance实例替换掉
                $params = $this->resolveDependencies($this->mergeParams($class, $params));
                // 调用$definition
                $object = call_user_func($definition, $this, $params, $config);
            } elseif (is_array($definition)) {
                // 如果是一个数组
                $concrete = $definition['class'];
                unset($definition['class']);
                // 合并配置和参数
                $config = array_merge($definition, $config);
                $params = $this->mergeParams($class, $params);
                if ($concrete === $class) {
                    $object = $this->build($class, $params, $config);
                } else {
                    $object = $this->get($concrete, $params, $config);
                }
            } elseif (is_object($definition)) {
                // 如果$definition是个对象,就直接保存到_singletons中
                return $this->_singletons[$class] = $definition;
            } else {
                throw new InvalidConfigException("Unexpected object definition type: " . gettype($definition));
            }
            if (array_key_exists($class, $this->_singletons)) {
                // singleton
                // 如果_singletons中没有这个类的实例,就保存一份
                $this->_singletons[$class] = $object;
            }
            return $object;
        }
  • 相关阅读:
    54:代码审计-TP5框架审计写法分析及代码追踪
    53:代码审计-TP5框架及无框架变量覆盖反序列化
    52:代码审计-PHP项目类RCE及文件包含下载删除
    51:代码审计-PHP框架MVC类上传断点调试挖掘
    支配树学习笔记
    模拟费用流学习笔记
    python之元类、双下方法( 双下方法也叫魔术方法、 内置方法)
    java 注解
    java 反射
    java synchronized
  • 原文地址:https://www.cnblogs.com/taokai/p/5470322.html
Copyright © 2020-2023  润新知