yii2源码学习笔记(九)
Application是所有应用程序类的基类,接下来了解一下它的源码。yii2\base\Application.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 yii\base; 9 10 use Yii; 11 12 /** 13 * Application is the base class for all application classes. 14 * 是所有应用程序类的基类 15 * @property \yii\web\AssetManager $assetManager The asset manager application component. This property is 16 * read-only.资产管理器应用组件,只读 17 * @property \yii\rbac\ManagerInterface $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 \yii\caching\Cache $cache The cache application component. Null if the component is not enabled. 21 * This property is read-only.缓存应用程序组件。 22 * @property \yii\db\Connection $db The database connection. This property is read-only.数据库连接。 23 * @property \yii\web\ErrorHandler|\yii\console\ErrorHandler $errorHandler The error handler application 24 * component. This property is read-only.错误处理程序应用程序组件 25 * @property \yii\i18n\Formatter $formatter The formatter application component. This property is read-only. 26 * 格式化程序的应用程序组件。 27 * @property \yii\i18n\I18N $i18n The internationalization application component. This property is read-only. 28 * 国际化应用组件。 29 * @property \yii\log\Dispatcher $log The log dispatcher application component. This property is read-only. 30 * 日志调度程序组件。 31 * @property \yii\mail\MailerInterface $mailer The mailer application component. This property is read-only. 32 * 邮件应用程序组件。 33 * @property \yii\web\Request|\yii\console\Request $request The request component. This property is read-only. 34 * 请求组件。 35 * @property \yii\web\Response|\yii\console\Response $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 \yii\base\Security $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 \yii\web\UrlManager $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|\yii\web\View $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 `app\controllers`. 105 * 此命名空间将用于负载控制器类重写它的控制器类的名字。 默认命名空间是`app\controllers`。 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 }
未完待续。