:-: **1 框架初始化过程**
>[info] 在入口文件(public/index.php)中,完成框架的基础环境搭建后
>
> 调用容器Container获取app应用对象,然后调用app的run()方法进行框架的整个运行过程。
>
> 在整个运行过程中,首先进行框架的初始化 包含app的initialize()和init()方法
>
> 所以框架的初始化在(/library/think/App.php)app的run()方法中完成
* * * * *
:-: **2 初始化**
[TOC]
## 2-1 initialize()
~~~
$this->beginTime = microtime(true);
$this->beginMem = memory_get_usage();
$this->thinkPath = dirname(dirname(__DIR__)) . '/';
$this->rootPath = dirname(realpath($this->appPath)) . '/';
$this->runtimePath = $this->rootPath . 'runtime/';
$this->routePath = $this->rootPath . 'route/';
$this->configPath = $this->rootPath . 'config/';
~~~
>[warning]1 设置运行信息。
> 框架开始运行时,开始运行内存 beginTime,beginMem
> 框架的各个主要目录
> thinkPath 框架目录
> rootPath 根目录
> runtimePath 运行时数据目录
> routePath 路由配置目录
> configPath 配置定义目录
~~~
$this->env->set([
'think_path' => $this->thinkPath,
'root_path' => $this->rootPath,
'app_path' => $this->appPath,
'config_path' => $this->configPath,
'route_path' => $this->routePath,
'runtime_path' => $this->runtimePath,
'extend_path' => $this->rootPath . 'extend/',
'vendor_path' => $this->rootPath . 'vendor/',
]);
~~~
>[warning] 2 存储目录参数到env属性中
> think_path 框架目录
> root_path 根目录
> app_path 应用目录
> config_path 配置文件目录
> route_path 路由配置目录
> runtime_path 运行时数据目录
> extend_path 自动加载目录
> vendor 扩展目录
>
~~~
if (is_file($this->rootPath . '.env')) {
$this->env->load($this->rootPath . '.env');
}
~~~
>[warning] 3 读取根目录下的.env文件 加载环境配置变量到env属性
~~~
$this->namespace = $this->env->get('app_namespace', $this->namespace);
$this->env->set('app_namespace', $this->namespace);
Loader::addNamespace($this->namespace, $this->appPath);
~~~
>[warning] 4 读取.env设置的app_namespace命名空间名称,如果没有配置,则读取app的namespace属性。默认为app
>然后设置env的app_namespace为应用命名空间名称app
>调用Loader的addNamespace注册命名空间名称app与应用目录/app的对应关系
~~~
$this->configExt = $this->env->get('config_ext', '.php');
~~~
>[warning] 5 读取配置文件后缀 默认为.php
~~~
$this->init();
~~~
>[warning] 6 应用初始化。初始化过程init()见下面
~~~
$this->suffix = $this->config('app.class_suffix');
~~~
>[warning] 7 获取类名后缀是否开启,默认不开启。开启是控制器和模型文件的文件名需要加上对应后缀
~~~
$this->debug = $this->env->get('app_debug', $this->config('app.app_debug'));
$this->env->set('app_debug', $this->debug);
if (!$this->debug) {
ini_set('display_errors', 'Off');
} elseif (PHP_SAPI != 'cli') {
//重新申请一块比较大的buffer
if (ob_get_level() > 0) {
$output = ob_get_clean();
}
ob_start();
if (!empty($output)) {
echo $output;
}
}
~~~
>[warning] 8 应用调试模式的开启
~~~
if (!empty($this->config('app.root_namespace'))) {
Loader::addNamespace($this->config('app.root_namespace'));
}
Loader::addClassAlias($this->config->pull('alias'));
~~~
>[warning] 9 注册命名空间与目录的对应 注册文件名与别名的对应关系
~~~
date_default_timezone_set($this->config('app.default_timezone'));
$this->loadLangPack();
~~~
>[warning] 10 设置系统时区和加载语言包
~~~
$this->hook->listen('app_init');
~~~
>[warning] 11 调用注册的app_init回调
## 2-2 init()
>[warning] 0 在initialize()中调用init()进行应用的初始化
>
>init()传入参数时,初始化对应的模块。参数为空时初始化整个应用。
>
>这里没有传入参数,进行整个应用的初始化
~~~
$module = $module ? $module . DIRECTORY_SEPARATOR : '';
$path = $this->appPath . $module;
~~~
>[warning] 1 进行初始化的目录 这里是应用的根目录/app/
~~~
if (is_file($path . 'init.php')) {
include $path . 'init.php';
} elseif (is_file($this->runtimePath . $module . 'init.php')) {
include $this->runtimePath . $module . 'init.php';
} else {
// 加载行为扩展文件
if (is_file($path . 'tags.php')) {
$this->hook->import(include $path . 'tags.php');
}
// 加载公共文件
if (is_file($path . 'common.php')) {
include $path . 'common.php';
}
if ('' == $module) {
// 加载系统助手函数
include $this->thinkPath . 'helper.php';
}
// 注册服务的容器对象实例
if (is_file($path . 'provider.php')) {
$this->container->bind(include $path . 'provider.php');
}
// 自动读取配置文件
if (is_dir($path . 'config')) {
$dir = $path . 'config';
} elseif (is_dir($this->configPath . $module)) {
$dir = $this->configPath . $module;
}
$files = isset($dir) ? scandir($dir) : [];
foreach ($files as $file) {
if ('.' . pathinfo($file, PATHINFO_EXTENSION) === $this->configExt) {
$filename = $dir . DIRECTORY_SEPARATOR . $file;
$this->config->load($filename, pathinfo($file, PATHINFO_FILENAME));
}
}
}
~~~
>[warning] 2 读取/app/init.php的初始化配置
> /app/init.php不存在时,则读取运行时目录/runtime/init.php文
>
> 如果不存在init.php文件,则读取其他配置文件
>[info] 其他配置文件包括 :
>
> 行为扩展 /app/tags.php.
> 公共内容文件 /app/common.php
> 助手函数文件 /app/helper.php
> 容器对象注册文件 /app/provider.php
> 读取配置目录下的配置文件 /app/config/xx.php。注册配置内容
~~~
$this->request->filter($this->config('app.default_filter'));
~~~
>[warning] 3 设置全局请求过滤方法
* * * * * *
:-: **3 请求调度与创建响应**
>[danger] 在app的run()方法中框架初始化后,开始进行请求调度
> 调度分派,执行应用对应的业务逻辑,
> 根据业务逻辑的处理结果,创建相应的响应对象
> 请求调度与创建响应 见 下一节的 请求响应
> 应用业务逻辑 见 MVC核心