yii2框架随笔8

今天我们继续来探索Component.php

 /**
     * Makes sure that the behaviors declared in [[behaviors()]] are attached to this component.   *确保在声明的行为[behaviors()]]安装此组件。
     */
    public function ensureBehaviors()
    {
        // 如果$this->_behaviors为空,获取$this->behaviors()中的behaviors,并存储到$this->_behaviors数组中
        if ($this->_behaviors === null) {
            $this->_behaviors = [];
            foreach ($this->behaviors() as $name => $behavior) {
                $this->attachBehaviorInternal($name, $behavior);
            }
        }
    }
    /**
     * Attaches a behavior to this component.
     *
     * 内部使用的为该对象添加behavior的方法
     *
     * @param string|integer $name the name of the behavior. If this is an integer, it means the behavior
     * is an anonymous one. Otherwise, the behavior is a named one and any existing behavior with the same name
     * will be detached first.
     * @param string|array|Behavior $behavior the behavior to be attached
     * @return Behavior the attached behavior.
     */
    private function attachBehaviorInternal($name, $behavior)
    {
        if (!($behavior instanceof Behavior)) {
            // $behavior不是Behavior对象,就认为是配置,通过它创建一个
            $behavior = Yii::createObject($behavior);
        }
        if (is_int($name)) {
            $behavior->attach($this);
            $this->_behaviors[] = $behavior;
        } else {
            if (isset($this->_behaviors[$name])) {
                // 存在就先解绑掉
                $this->_behaviors[$name]->detach();
            }
            $behavior->attach($this);
            $this->_behaviors[$name] = $behavior;
        }
        return $behavior;
    }

下面我们来看一下Application.php

<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */
namespace yii\base;
use Yii;

abstract class Application extends Module
{

 const EVENT_BEFORE_REQUEST = ‘beforeRequest‘;
    /**
     * @event Event an event raised after the application successfully handles a request (before the response is sent out).   *事件引发的事件后,该应用程序成功处理请求的事件(发出的响应)
     */
    const EVENT_AFTER_REQUEST = ‘afterRequest‘;
    /**
     * Application state used by [[state]]: application just started.   
     */
    const STATE_BEGIN = 0;
    /**
     * Application state used by [[state]]: application is initializing.   *应用程序正在初始化:由[state]使用的应用程序状态
     */
    const STATE_INIT = 1;
    /**
     * Application state used by [[state]]: application is triggering [[EVENT_BEFORE_REQUEST]].   *应用程序触发[EVENT BEFORE_REQUEST]:由[state]使用应用程序状态。
     */
    const STATE_BEFORE_REQUEST = 2;
/**
     * Constructor.
     * @param array $config name-value pairs that will be used to initialize the object properties.
     * Note that the configuration must contain both [[id]] and [[basePath]].
     * @throws InvalidConfigException if either [[id]] or [[basePath]] configuration is missing.
     */
    public function __construct($config = [])
    {
        // 将自身的实例绑到Yii的$app上
        Yii::$app = $this;
        // 将自身加入到loadedModules中
        $this->setInstance($this);
        // 设置状态为刚开始
        $this->state = self::STATE_BEGIN;
        // 做预处理,包括设置alias和merge核心components的配置
        $this->preInit($config);
        $this->registerErrorHandler($config);
        Component::__construct($config);
    }
    /**
     * Pre-initializes the application.
     * This method is called at the beginning of the application constructor.
     * It initializes several important application properties.
     * If you override this method, please make sure you call the parent implementation.   *预先初始化应用程序。 这种方法被称为在应用程序构造的开始。    *它初始化一些重要的应用程序属性。    *如果您覆盖此方法,请确保您调用父类的实现。
     * @param array $config the application configuration
     * @throws InvalidConfigException if either [[id]] or [[basePath]] configuration is missing.
     */
    public function preInit(&$config)
    {
        // 使用了&符号,表示$config的修改会保留
        if (!isset($config[‘id‘])) {
            throw new InvalidConfigException(‘The "id" configuration for the Application is required.‘);
        }
        if (isset($config[‘basePath‘])) {
            // 项目的root路径
            $this->setBasePath($config[‘basePath‘]);
            // 用完删掉
            unset($config[‘basePath‘]);
        } else {
            throw new InvalidConfigException(‘The "basePath" configuration for the Application is required.‘);
        }
        if (isset($config[‘vendorPath‘])) {
            $this->setVendorPath($config[‘vendorPath‘]);
            unset($config[‘vendorPath‘]);
        } else {
            // 不存在,就设置默认值
            // set "@vendor"
            $this->getVendorPath();
        }
        if (isset($config[‘runtimePath‘])) {
            $this->setRuntimePath($config[‘runtimePath‘]);
            unset($config[‘runtimePath‘]);
        } else {
            // 不存在,就设置默认值
            // set "@runtime"
            $this->getRuntimePath();
        }
        if (isset($config[‘timeZone‘])) {
            $this->setTimeZone($config[‘timeZone‘]);
            unset($config[‘timeZone‘]);
        } elseif (!ini_get(‘date.timezone‘)) {
            // 默认时区是零时区
            $this->setTimeZone(‘UTC‘);
        }
        // merge core components with custom components
        foreach ($this->coreComponents() as $id => $component) {
            if (!isset($config[‘components‘][$id])) {
                // 如果配置中没有配置相应的核心component,就赋给它
                $config[‘components‘][$id] = $component;
            } elseif (is_array($config[‘components‘][$id]) && !isset($config[‘components‘][$id][‘class‘])) {
                // 如果存在相应的核心component,但没有定义它的class,就直接赋到class的key上
                $config[‘components‘][$id][‘class‘] = $component[‘class‘];
            }
        }
    }
    /**
     * @inheritdoc
     */
    public function init()
    {
        $this->state = self::STATE_INIT;
        $this->bootstrap();
    }
 /**
     * Registers the errorHandler component as a PHP error handler.   *注册的errorHandler组件作为PHP错误处理程序。
     * @param array $config application config
     */
    protected function registerErrorHandler(&$config)
    {
        // YII_ENABLE_ERROR_HANDLER,在BaseYii中被定义为true
        if (YII_ENABLE_ERROR_HANDLER) {
            if (!isset($config[‘components‘][‘errorHandler‘][‘class‘])) {
                echo "Error: no errorHandler component is configured.\n";
                exit(1);
            }
            // 其实质是将$config[‘components‘][‘errorHandler‘]的内容设置到了$this->_definitions[‘errorHandler‘]中
            $this->set(‘errorHandler‘, $config[‘components‘][‘errorHandler‘]);
            // 删除掉errorHandler的配置内容
            unset($config[‘components‘][‘errorHandler‘]);
            $this->getErrorHandler()->register();
        }
    }

   /**
     * Returns the directory that stores runtime files.   * 返回存储运行时文件的目录。
     * @return string the directory that stores runtime files.
     * Defaults to the "runtime" subdirectory under [[basePath]].
     */
    public function getRuntimePath()
    {
        if ($this->_runtimePath === null) {
            // 不存在,就将其设置为basePath/runtime
            $this->setRuntimePath($this->getBasePath() . DIRECTORY_SEPARATOR . ‘runtime‘);
        }
        return $this->_runtimePath;
    }
时间: 2024-12-09 22:34:13

yii2框架随笔8的相关文章

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

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 yii\di; use ReflectionClass; use yii\base\Component; use yii\bas