• yii2源码学习笔记(九)


    Application是所有应用程序类的基类,接下来了解一下它的源码。yii2aseApplication.php。

      1 <?php
      2 /**
      3  * @link http://www.yiiframework.com/
      4  * @copyright Copyright (c) 2008 Yii Software LLC
      5  * @license http://www.yiiframework.com/license/
      6  */
      7 
      8 namespace yiibase;
      9 
     10 use Yii;
     11 
     12 /**
     13  * Application is the base class for all application classes.
     14  * 是所有应用程序类的基类
     15  * @property yiiwebAssetManager $assetManager The asset manager application component. This property is
     16  * read-only.资产管理器应用组件,只读
     17  * @property yii
    bacManagerInterface $authManager The auth manager application component. Null is returned
     18  * if auth manager is not configured. This property is read-only.认证管理器应用程序组件。未配置返回null,只读
     19  * @property string $basePath The root directory of the application. 应用程序的根目录。
     20  * @property yiicachingCache $cache The cache application component. Null if the component is not enabled.
     21  * This property is read-only.缓存应用程序组件。
     22  * @property yiidbConnection $db The database connection. This property is read-only.数据库连接。
     23  * @property yiiwebErrorHandler|yiiconsoleErrorHandler $errorHandler The error handler application
     24  * component. This property is read-only.错误处理程序应用程序组件
     25  * @property yiii18nFormatter $formatter The formatter application component. This property is read-only.
     26  * 格式化程序的应用程序组件。
     27  * @property yiii18nI18N $i18n The internationalization application component. This property is read-only.
     28  * 国际化应用组件。
     29  * @property yiilogDispatcher $log The log dispatcher application component. This property is read-only.
     30  * 日志调度程序组件。
     31  * @property yiimailMailerInterface $mailer The mailer application component. This property is read-only.
     32  * 邮件应用程序组件。
     33  * @property yiiwebRequest|yiiconsoleRequest $request The request component. This property is read-only.
     34  * 请求组件。
     35  * @property yiiwebResponse|yiiconsoleResponse $response The response component. This property is
     36  * read-only.反应元件。
     37  * @property string $runtimePath The directory that stores runtime files. Defaults to the "runtime"
     38  * subdirectory under [[basePath]].存储运行时文件的目录。
     39  * @property yiiaseSecurity $security The security application component. This property is read-only.
     40  * 安全应用组件。
     41  * @property string $timeZone The time zone used by this application.该应用程序使用的时区。
     42  * @property string $uniqueId The unique ID of the module. This property is read-only.模块的唯一标识。
     43  * @property yiiwebUrlManager $urlManager The URL manager for this application. This property is read-only.
     44  * 此应用程序的网址管理器。
     45  * @property string $vendorPath The directory that stores vendor files. Defaults to "vendor" directory under
     46  * [[basePath]].存储供应商文件的目录。
     47  * @property View|yiiwebView $view The view application component that is used to render various view
     48  * files. This property is read-only.用于呈现各种视图文件的视图应用程序组件
     49  *
     50  * @author Qiang Xue <qiang.xue@gmail.com>
     51  * @since 2.0
     52  */
     53 abstract class Application extends Module
     54 {
     55     /**
     56      * @event Event an event raised before the application starts to handle a request.
     57      * 在应用程序开始处理请求之前提出的事件。
     58      */
     59     const EVENT_BEFORE_REQUEST = 'beforeRequest';
     60     /**
     61      * @event Event an event raised after the application successfully handles a request (before the response is sent out).
     62      * 该应用程序成功处理请求后提出的事件
     63      */
     64     const EVENT_AFTER_REQUEST = 'afterRequest';
     65     /**
     66      * Application state used by [[state]]: application just started.
     67      * [[state]]适用状态:刚开始应用
     68      */
     69     const STATE_BEGIN = 0;
     70     /**
     71      * Application state used by [[state]]: application is initializing.
     72      *  [[state]]应用程序状态:应用程序初始化。
     73      */
     74     const STATE_INIT = 1;
     75     /**
     76      * Application state used by [[state]]: application is triggering [[EVENT_BEFORE_REQUEST]].
     77      *  [[state]]应用程序状态:应用触发[[EVENT_BEFORE_REQUEST]]
     78      */
     79     const STATE_BEFORE_REQUEST = 2;
     80     /**
     81      * Application state used by [[state]]: application is handling the request.
     82      *  [[state]]应用程序状态:应用程序处理请求。
     83      */
     84     const STATE_HANDLING_REQUEST = 3;
     85     /**
     86      * Application state used by [[state]]: application is triggering [[EVENT_AFTER_REQUEST]]..
     87      *  [[state]]应用程序状态:应用触发[[EVENT_AFTER_REQUEST]]
     88      */
     89     const STATE_AFTER_REQUEST = 4;
     90     /**
     91      * Application state used by [[state]]: application is about to send response.
     92      *  [[state]]应用程序状态:应用程序即将发送响应。
     93      */
     94     const STATE_SENDING_RESPONSE = 5;
     95     /**
     96      * Application state used by [[state]]: application has ended.
     97      *  [[state]]应用程序状态:应用程序结束。
     98      */
     99     const STATE_END = 6;
    100 
    101     /**
    102      * @var string the namespace that controller classes are located in.控制器类的命名空间位置。
    103      * This namespace will be used to load controller classes by prepending it to the controller class name.
    104      * The default namespace is `appcontrollers`.
    105      * 此命名空间将用于负载控制器类重写它的控制器类的名字。 默认命名空间是`appcontrollers`。
    106      * Please refer to the [guide about class autoloading](guide:concept-autoloading.md) for more details.
    107      */
    108     public $controllerNamespace = 'app\controllers';
    109     /**
    110      * @var string the application name.应用程序名称。
    111      */
    112     public $name = 'My Application';
    113     /**
    114      * @var string the version of this application.此应用程序的版本。
    115      */
    116     public $version = '1.0';
    117     /**
    118      * @var string the charset currently used for the application.目前使用的字符集。
    119      */
    120     public $charset = 'UTF-8';
    121     /**
    122      * @var string the language that is meant to be used for end users. It is recommended that you
    123      * use [IETF language tags](http://en.wikipedia.org/wiki/IETF_language_tag). For example, `en` stands
    124      * for English, while `en-US` stands for English (United States).
    125      * 用来作为终端用户使用的语言
    126      * @see sourceLanguage
    127      */
    128     public $language = 'en-US';
    129     /**
    130      * @var string the language that the application is written in. This mainly refers to
    131      * the language that the messages and view files are written in.
    132      * 应用程序编写的语言。
    133      * @see language
    134      */
    135     public $sourceLanguage = 'en-US';
    136     /**
    137      * @var Controller the currently active controller instance当前活动控制器实例
    138      */
    139     public $controller;
    140     /**
    141      * @var string|boolean the layout that should be applied for views in this application. Defaults to 'main'.
    142      * If this is false, layout will be disabled.
    143      * 该应用程序中应用的布局。
    144      */
    145     public $layout = 'main';
    146     /**
    147      * @var string the requested route请求的路径    请求的路径
    148      */
    149     public $requestedRoute;
    150     /**
    151      * @var Action the requested Action. If null, it means the request cannot be resolved into an action.
    152      * 操作所要求的行动
    153      */
    154     public $requestedAction;
    155     /**
    156      * @var array the parameters supplied to the requested action.
    157      * 所请求的动作提供的参数。
    158      */
    159     public $requestedParams;
    160     /**
    161      * @var array list of installed Yii extensions. Each array element represents a single extension
    162      * with the following structure:
    163      * 安装Yii扩展名列表。每个数组元素代表一个扩展
    164      *
    165      * ~~~
    166      * [
    167      *     'name' => 'extension name',
    168      *     'version' => 'version number',
    169      *     'bootstrap' => 'BootstrapClassName',  // optional, may also be a configuration array
    170      *     'alias' => [
    171      *         '@alias1' => 'to/path1',
    172      *         '@alias2' => 'to/path2',
    173      *     ],
    174      * ]
    175      * ~~~
    176      *
    177      * The "bootstrap" class listed above will be instantiated during the application
    178      * [[bootstrap()|bootstrapping process]]. If the class implements [[BootstrapInterface]],
    179      * its [[BootstrapInterface::bootstrap()|bootstrap()]] method will be also be called.
    180      *
    181      * If not set explicitly in the application config, this property will be populated with the contents of
    182      * 如果在应用程序配置中没有设置,该属性将填充到内容
    183      * @vendor/yiisoft/extensions.php`.
    184      */
    185     public $extensions;
    186     /**
    187      * @var array list of components that should be run during the application [[bootstrap()|bootstrapping process]].
    188      * 组件的列表,运行在 [[bootstrap()|bootstrapping process]]中的应用
    189      * Each component may be specified in one of the following formats:
    190      *
    191      * - an application component ID as specified via [[components]].
    192      * - a module ID as specified via [[modules]].
    193      * - a class name.
    194      * - a configuration array.
    195      *
    196      * During the bootstrapping process, each component will be instantiated. If the component class
    197      * implements [[BootstrapInterface]], its [[BootstrapInterface::bootstrap()|bootstrap()]] method
    198      * will be also be called.
    199      * 在整个启动过程中,每个组件被实例化。如果组件类提到 [[BootstrapInterface]], 
    200      * [[BootstrapInterface::bootstrap()|bootstrap()]]方法也会调用
    201      */
    202     public $bootstrap = [];
    203     /**
    204      * @var integer the current application state during a request handling life cycle.
    205      * This property is managed by the application. Do not modify this property.    
    206      * 在请求处理生命周期中的当前应用程序状态。属性由应用程序管理。不要修改此属性。
    207      */
    208     public $state;
    209     /**
    210      * @var array list of loaded modules indexed by their class names.
    211      * 加载模块列表由它们的类名称索引组成。
    212      */
    213     public $loadedModules = [];
    214 
    215 
    216     /**
    217      * Constructor.构造函数
    218      * @param array $config name-value pairs that will be used to initialize the object properties.
    219      * Note that the configuration must contain both [[id]] and [[basePath]].
    220      * 用来初始化对象属性的 name-value 注意配置必须包含[[id]] 和[[basePath]].
    221      * @throws InvalidConfigException if either [[id]] or [[basePath]] configuration is missing.
    222      * 如果是修改[[id]] 或[[basePath]] 则配置丢失。
    223      */
    224     public function __construct($config = [])
    225     {
    226         Yii::$app = $this;// 将自身的实例绑到Yii的$app上
    227         $this->setInstance($this);// 将自身加入到loadedModules中
    228 
    229         $this->state = self::STATE_BEGIN;// 设置状态为刚开始
    230 
    231         // 做预处理配置
    232         $this->preInit($config);
    233 
    234         $this->registerErrorHandler($config);
    235 
    236         Component::__construct($config);
    237     }
    238 
    239     /**
    240      * Pre-initializes the application. 初始化应用。
    241      * This method is called at the beginning of the application constructor.
    242      * It initializes several important application properties.
    243      * 在构造函数中调用该方法,用于初始化一些重要的属性
    244      * If you override this method, please make sure you call the parent implementation.
    245      * @param array $config the application configuration   应用的配置
    246      * @throws InvalidConfigException if either [[id]] or [[basePath]] configuration is missing.
    247      */
    248     public function preInit(&$config)
    249     {
    250          // 使用了&符号,表示$config的修改会保留
    251         if (!isset($config['id'])) {//判断配置中是否有application ID ,如果没有,抛出异常
    252             throw new InvalidConfigException('The "id" configuration for the Application is required.');
    253         }
    254         if (isset($config['basePath'])) {
    255             // 是否配置项目的root路径
    256             $this->setBasePath($config['basePath']);
    257              //赋值给模块的_basepath属性,并在设置后删除
    258             unset($config['basePath']);
    259         } else {//否则抛出异常
    260             throw new InvalidConfigException('The "basePath" configuration for the Application is required.');
    261         }
    262         //如果配置文件中设置了 vendorPath 使用配置的值,并在设置后删除,否则使用默认的
    263         if (isset($config['vendorPath'])) {
    264             $this->setVendorPath($config['vendorPath']);
    265             unset($config['vendorPath']);
    266         } else {
    267             // set "@vendor"
    268             $this->getVendorPath();
    269         }
    270         //如果配置文件中设置了 runtimePath 使用配置的值,并在设置后删除,否则使用默认的
    271         if (isset($config['runtimePath'])) {
    272             $this->setRuntimePath($config['runtimePath']);
    273             unset($config['runtimePath']);
    274         } else {
    275             // set "@runtime"
    276             $this->getRuntimePath();
    277         }
    278          //如果配置文件中设置了 timeZone 使用配置的值,并在设置后删除,否则使用默认的时区
    279         if (isset($config['timeZone'])) {
    280             $this->setTimeZone($config['timeZone']);
    281             unset($config['timeZone']);
    282         } elseif (!ini_get('date.timezone')) {
    283             $this->setTimeZone('UTC');
    284         }
    285 
    286         // merge core components with custom components
    287         foreach ($this->coreComponents() as $id => $component) {
    288             if (!isset($config['components'][$id])) {
    289                 // 如果配置中没有配置相应的核心component,就赋给它
    290                 $config['components'][$id] = $component;
    291             } elseif (is_array($config['components'][$id]) && !isset($config['components'][$id]['class'])) {
    292                  // 如果存在相应的核心component,但没有定义它的class,就直接赋到class的key上
    293                 $config['components'][$id]['class'] = $component['class'];
    294             }
    295         }
    296     }
    297 
    298     /**
    299      * @inheritdoc
    300      */
    301     public function init()
    302     {
    303         $this->state = self::STATE_INIT;
    304         $this->bootstrap();
    305     }
    306 
    307     /**
    308      * Initializes extensions and executes bootstrap components.初始化扩展并执行初始化程序组件
    309      * This method is called by [[init()]] after the application has been fully configured.
    310      * 该方法在应用完全配置后被[[init()]]调用
    311      * If you override this method, make sure you also call the parent implementation.
    312      */
    313     protected function bootstrap()
    314     {
    315         if ($this->extensions === null) {//如果没有配置,则调用Yii的默认扩展组件
    316             $file = Yii::getAlias('@vendor/yiisoft/extensions.php');
    317             $this->extensions = is_file($file) ? include($file) : [];
    318         }
    319         foreach ($this->extensions as $extension) {
    320             if (!empty($extension['alias'])) {//如果扩展组件有设置别名
    321                 foreach ($extension['alias'] as $name => $path) {
    322                     Yii::setAlias($name, $path);//将给扩展的别名注册到别名数组中
    323                 }
    324             }
    325             if (isset($extension['bootstrap'])) {//如果扩展组件有[[bootstrap]]配置 则初始化给扩展组件
    326                 $component = Yii::createObject($extension['bootstrap']);
    327                 if ($component instanceof BootstrapInterface) {
    328                     Yii::trace("Bootstrap with " . get_class($component) . '::bootstrap()', __METHOD__);
    329                     $component->bootstrap($this);
    330                 } else {
    331                     Yii::trace("Bootstrap with " . get_class($component), __METHOD__);
    332                 }
    333             }
    334         }
    335 
    336         foreach ($this->bootstrap as $class) {
    337             $component = null;
    338             if (is_string($class)) {
    339                 if ($this->has($class)) {
    340                     $component = $this->get($class);
    341                 } elseif ($this->hasModule($class)) {
    342                     $component = $this->getModule($class);
    343                 } elseif (strpos($class, '\') === false) {
    344                     throw new InvalidConfigException("Unknown bootstrapping component ID: $class");
    345                 }
    346             }
    347             if (!isset($component)) {//如果不存在,则调用Yii创建对象
    348                 $component = Yii::createObject($class);
    349             }
    350 
    351             if ($component instanceof BootstrapInterface) {
    352                 Yii::trace("Bootstrap with " . get_class($component) . '::bootstrap()', __METHOD__);
    353                 $component->bootstrap($this);
    354             } else {
    355                 Yii::trace("Bootstrap with " . get_class($component), __METHOD__);
    356             }
    357         }
    358     }

    未完待续。

  • 相关阅读:
    观察者模式
    hdu 4712 Hamming Distance bfs
    leetcode Sum Root to Leaf Numbers(所有路径之和)
    Oracle实用-01:绑定变量
    jQuery实现AJAX定时刷新局部页面实例
    给Ajax一个漂亮的嫁衣——Ajax系列之五(下)之序列化和反序列化
    jquery的ajax同步和异步
    报表技术
    告别.NET生成报表统计图的烦恼
    浅谈ASP.NET报表控件
  • 原文地址:https://www.cnblogs.com/dragon16/p/5547511.html
Copyright © 2020-2023  润新知