yii2框架随笔28

今天来看一下ServiceLocator.php

文件目录:di/ServiceLocator.php

<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */
namespace yii\di;
use Yii;
use Closure;
use yii\base\Component;
use yii\base\InvalidConfigException;
/**
 * ServiceLocator implements a [service locator](http://en.wikipedia.org/wiki/Service_locator_pattern).
 * servicelocator实现[服务定位器](http://en.wikipedia.org/wiki/service_locator_pattern).
 * To use ServiceLocator, you first need to register component IDs with the corresponding component
 * definitions with the locator by calling [[set()]] or [[setComponents()]].
 * 使用servicelocator,您首先需要注册组件与相应组件的入侵检测系统定义和定位通过调用set()或者[ setcomponents() ] 。
 * You can then call [[get()]] to retrieve a component with the specified ID. The locator will automatically
 * instantiate and configure the component according to the definition.
 * 然后你可以调用get() [ [ ] ]检索组件与指定的ID。
 * For example,
 *
 * ```php
 * $locator = new \yii\di\ServiceLocator;
 * $locator->setComponents([
 *     ‘db‘ => [
 *         ‘class‘ => ‘yii\db\Connection‘,
 *         ‘dsn‘ => ‘sqlite:path/to/file.db‘,
 *     ],
 *     ‘cache‘ => [
 *         ‘class‘ => ‘yii\caching\DbCache‘,
 *         ‘db‘ => ‘db‘,
 *     ],
 * ]);
 *
 * ```
 *
 * Because [[\yii\base\Module]] extends from ServiceLocator, modules and the application are all service locators.
 *
 * @property array $components The list of the component definitions or the loaded component instances (ID =>
 * definition or instance).
 *
 * @author Qiang Xue <[email protected]>
 * @since 2.0
 */
class ServiceLocator extends Component
{
    /**
     * 存储component的实例,key是component的ID
     * @var array shared component instances indexed by their IDs
     */
    private $_components = [];
    /**
     * 存储component的配置,key是component的ID
     * @var array component definitions indexed by their IDs
     */
    private $_definitions = [];
    /**
     * Getter magic method.
     * This method is overridden to support accessing components like reading properties.
     * @param string $name component or property name
     * @return mixed the named property value
     */
    public function __get($name)
    {
        // 获取component,只要定义中有,就可以拿到
        // 未实例化,get方法会去实例化
        if ($this->has($name)) {
            return $this->get($name);
        } else {
            return parent::__get($name);
        }
    }
    /**
     * Checks if a property value is null.
     * 检查属性值是否为空。
     * This method overrides the parent implementation by checking if the named component is loaded.
     * 该方法覆盖了父类的实现通过检查如果命名组件加载。
     * @param string $name the property name or the event name
     * @return boolean whether the property value is null
     */
    public function __isset($name)
    {
        // 可以看到,如果用isset去判断是否含有某个component,只能判断已经实例化过的component
        if ($this->has($name, true)) {
            return true;
        } else {
            return parent::__isset($name);
        }
    }
    /**
     * Returns a value indicating whether the locator has the specified component definition or has instantiated the component.
     * 返回一个值,指示是否定位具有指定的组件定义和实例化的组件。
     * This method may return different results depending on the value of `$checkInstance`.
     * 此方法可能会返回不同的结果取决于价值`$checkinstance`。
     *
     * @param string $id component ID (e.g. `db`).
     * @param boolean $checkInstance whether the method should check if the component is shared and instantiated.
     * @return boolean whether the locator has the specified component definition or has instantiated the component.
     * @see set()
     */
    public function has($id, $checkInstance = false)
    {
        // 如果要检查是否有component的实例,就将$checkInstance设置为true
        return $checkInstance ? isset($this->_components[$id]) : isset($this->_definitions[$id]);
    }
    /**
     * Returns the component instance with the specified ID.
     * 返回指定的标识的组件实例。
     * @param string $id component ID (e.g. `db`).
     * @param boolean $throwException whether to throw an exception if `$id` is not registered with the locator before.
     * @return object|null the component of the specified ID. If `$throwException` is false and `$id`
     * is not registered before, null will be returned.
     * @throws InvalidConfigException if `$id` refers to a nonexistent component ID
     * @see has()
     * @see set()
     */
    public function get($id, $throwException = true)
    {
        if (isset($this->_components[$id])) {
            // 如果存在就直接返回
            return $this->_components[$id];
        }
        if (isset($this->_definitions[$id])) {
            // 存在component的配置
            $definition = $this->_definitions[$id];
            // 是一个object还不是匿名函数,就代表是一个component的实例
            // 继承自Closure代表是一个匿名函数
            if (is_object($definition) && !$definition instanceof Closure) {
                return $this->_components[$id] = $definition;
            } else {
                // 不是component的实例,就根据配置去创建一个
                return $this->_components[$id] = Yii::createObject($definition);
            }
        } elseif ($throwException) {
            // 都不存在并且允许抛异常的话,就抛异常
            throw new InvalidConfigException("Unknown component ID: $id");
        } else {
            return null;
        }
    }
时间: 2024-12-24 04:02:47

yii2框架随笔28的相关文章

yii2框架随笔21

今天来看一下BaseYii.php <?php /** * @link http://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC * @license http://www.yiiframework.com/license/ */ namespace yii; use yii\base\InvalidConfigException; use yii\base\InvalidParamExceptio

yii2框架随笔4

接下来我们继续了解Component.php 目录为:vendor/yiisoft/yii2/base/Component.php (接上次的代码) /** * Sets the value of a component property. *设置一个组件属性的值. * This method will check in the following order and act accordingly: *这种方法将检查以下顺序并采取相应的行动: * - a property defined by

yii2框架随笔30

今天来看console/Application.php <?php /** * @link http://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC * @license http://www.yiiframework.com/license/ */ namespace yii\console; use Yii; use yii\base\InvalidRouteException; /** * A

yii2框架随笔23

今天继续阅读BaseYii.php <?php /** * Class autoload loader. * 自动装载类加载程序. * This method is invoked automatically when PHP sees an unknown class. * PHP用该方法自动调用一个未知类. * The method will attempt to include the class file according to the following procedure: * 方

yii2框架随笔22

今天继续来看BaseYii.php <?php /** * Returns the root alias part of a given alias. * 返回根别名的一部分,一个给定的别名. * A root alias is an alias that has been registered via [[setAlias()]] previously. * 根别名是已经注册别名通过[[setAlias()]]. * If a given alias matches multiple root

yii2框架随笔3

今天开始阅读vendor/yiisoft/yii2/base/Action.php <?php namespace yii\base;//命名空间 use Yii;//加载Yii文件夹下的Yii.php /** * Action is the base class for all controller action classes. * * Action provides a way to reuse action method code. An action method in an Acti

yii2框架随笔36

今天来看一下vendor/yiisoft/yii2/base/Event.php <?php namespace yii\base; //事件是所有事件类的基类.它封装了参数与事件相关联. //如果一个事件处理程序集[[进行]]是真的,其余的,uninvoked处理程序将不再被称为处理事件. //另外,添加一个事件处理程序时,额外的数据可能被传递和可以通过[[数据]]属性调用事件处理程序时. class Event extends Object { /** * @var string the e

yii2框架随笔37

vendor/yiisoft/yii2/base/Event.php <?php namespace yii\base; //事件是所有事件类的基类.它封装了参数与事件相关联. //如果一个事件处理程序集[[进行]]是真的,其余的,uninvoked处理程序将不再被称为处理事件. //另外,添加一个事件处理程序时,额外的数据可能被传递和可以通过[[数据]]属性调用事件处理程序时. class Event extends Object { /** * @var string the event n

yii2框架随笔35

今天来看vendor/yiisoft/yii2/base/Event.php <?php namespace yii\base; //事件是所有事件类的基类.它封装了参数与事件相关联. //如果一个事件处理程序集[[进行]]是真的,其余的,uninvoked处理程序将不再被称为处理事件. //另外,添加一个事件处理程序时,额外的数据可能被传递和可以通过[[数据]]属性调用事件处理程序时. class Event extends Object { /** * @var string the eve