目录
一、构造函数
1. 挂载app实例
2. 状态初始化
3. 预初始化
4. 注册错误处理程序
5. 调用父类的构造函数
/**
* 构造函数
* 1. 挂载app实例
* 2. 状态初始化
* 3. 预初始化
* 4. 注册错误处理程序
* 5. 调用父类的构造函数
*/
public function __construct($config = [])
{
//挂载app实例
Yii::$app = $this;
static::setInstance($this);
//状态初始化
$this->state = self::STATE_BEGIN;
//预初始化
$this->preInit($config);
//注册错误处理程序
$this->registerErrorHandler($config);
Component::__construct($config);
}
二、preInit方法,检查和初始化应用程序配置
1. 检查应用程序id
2. 检查并设置basePath,设置@app别名
3. 设置@vendor别名
4. 设置@runtime别名
5. 时区设置
6. 设置容器属性
7. 合并核心组件与自定义组件
/**
* 检查和初始化应用程序配置
* 1. 检查应用程序id
* 2. 检查并设置basePath,设置@app别名
* 3. 设置@vendor别名
* 4. 设置@runtime别名
* 5. 时区设置
* 6. 设置容器属性
* 7. 合并核心组件与自定义组件
*/
public function preInit(&$config)
{
//检查应用程序id
if (!isset($config['id'])) {
throw new InvalidConfigException('The "id" configuration for the Application is required.');
}
//检查并设置basePath
if (isset($config['basePath'])) {
//设置@app别名
$this->setBasePath($config['basePath']);
unset($config['basePath']);
} else {
throw new InvalidConfigException('The "basePath" configuration for the Application is required.');
}
if (isset($config['vendorPath'])) {
//设置@vendor别名
$this->setVendorPath($config['vendorPath']);
unset($config['vendorPath']);
} else {
// set "@vendor"
$this->getVendorPath();
}
if (isset($config['runtimePath'])) {
//设置@runtime别名
$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');
}
//设置容器属性
if (isset($config['container'])) {
$this->setContainer($config['container']);
unset($config['container']);
}
// 合并核心组件与自定义组件
foreach ($this->coreComponents() as $id => $component) {
if (!isset($config['components'][$id])) {
$config['components'][$id] = $component;
} elseif (is_array($config['components'][$id]) && !isset($config['components'][$id]['class'])) {
$config['components'][$id]['class'] = $component['class'];
}
}
}
三、init方法,可以实现对象的一些初始化工作
1. 应用状态设置
2. 扩展初始化,加载启动组件
/**
* 初始化对象工作
* 1. 应用状态设置
* 2. 扩展初始化,加载启动组件
*/
public function init()
{
//应用状态设置
$this->state = self::STATE_INIT;
//扩展初始化,加载启动组件
$this->bootstrap();
}
四、bootstrap方法,启动方法
1. 扩展初始化
2. 加载启动组件
/**
* 1. 扩展初始化
* 2. 加载启动组件
*/
protected function bootstrap()
{
//加载扩展配置
if ($this->extensions === null) {
$file = Yii::getAlias('@vendor/yiisoft/extensions.php');
$this->extensions = is_file($file) ? include $file : [];
}
foreach ($this->extensions as $extension) {
//设置别名
if (!empty($extension['alias'])) {
foreach ($extension['alias'] as $name => $path) {
Yii::setAlias($name, $path);
}
}
//启动项
if (isset($extension['bootstrap'])) {
// $extension['bootstrap']可以是
// 类名称,配置数组
$component = Yii::createObject($extension['bootstrap']);
// $component实现了BootstrapInterface接口,
//则也调用其bootstrap方法
if ($component instanceof BootstrapInterface) {
Yii::debug('Bootstrap with ' . get_class($component) . '::bootstrap()', __METHOD__);
$component->bootstrap($this);
} else {
Yii::debug('Bootstrap with ' . get_class($component), __METHOD__);
}
}
}
// string: 组件id,模块id,类名称,
// array: 配置数组
// closure: 闭包
foreach ($this->bootstrap as $mixed) {
$component = null;
if ($mixed instanceof \Closure) {// 闭包
Yii::debug('Bootstrap with Closure', __METHOD__);
if (!$component = call_user_func($mixed, $this)) {
continue;
}
} elseif (is_string($mixed)) {// 组件id,模块id,类名称,
if ($this->has($mixed)) {
$component = $this->get($mixed);
} elseif ($this->hasModule($mixed)) {
$component = $this->getModule($mixed);
} elseif (strpos($mixed, '\\') === false) {
throw new InvalidConfigException("Unknown bootstrapping component ID: $mixed");
}
}
if (!isset($component)) {// 配置数组
$component = Yii::createObject($mixed);
}
// $component实现了BootstrapInterface接口,
//则也调用其bootstrap方法
if ($component instanceof BootstrapInterface) {
Yii::debug('Bootstrap with ' . get_class($component) . '::bootstrap()', __METHOD__);
$component->bootstrap($this);
} else {
Yii::debug('Bootstrap with ' . get_class($component), __METHOD__);
}
}
}
五、registerErrorHandler方法,注册错误处理函数
/**
* 注册错误处理函数
*/
protected function registerErrorHandler(&$config)
{
//YII_ENABLE_ERROR_HANDLER常量设置是否启用
// 错误处理
if (YII_ENABLE_ERROR_HANDLER) {
// 组件类需要指定 class 字段
if (!isset($config['components']['errorHandler']['class'])) {
echo "Error: no errorHandler component is configured.\n";
exit(1);
}
$this->set('errorHandler', $config['components']['errorHandler']);
unset($config['components']['errorHandler']);
$this->getErrorHandler()->register();
}
}
总结:
阅读了5个方法:
- __construct构造函数
- preInit方法,检查和初始化应用程序配置
- init方法,可以实现对象的一些初始化工作
- bootstrap方法,启动方法
- registerErrorHandler方法,注册错误处理函数