7.执行HTTP应用类的run方法启动一个HTTP应用
tp6\public\index.php
$response = $http->run();
8.获取当前请求对象实例(默认为 app\Request
继承think\Request
)保存到容器
tp6\vendor\topthink\framework\src\think\Http->run
$request = $request ?? $this->app->make('request', [], true);
$this->app->instance('request', $request);
9.执行think\App
类的初始化方法initialize
//tp6\vendor\topthink\framework\src\think\Http->run
$this->initialize();
//tp6\vendor\topthink\framework\src\think\Http->initialize
$this->app->initialize();
10.加载环境变量文件.env
和全局初始化文件
//tp6\vendor\topthink\framework\src\think\App->initialize
$this->loadEnv($this->envName); //$this->envName 是个""
// 加载环境变量
$envFile = $envName ? $this->rootPath . '.env.' . $envName : $this->rootPath . '.env';
if (is_file($envFile)) {
$this->env->load($envFile);
}
//tp6\vendor\topthink\framework\src\think\Env->load
//分析配置文件
$env = parse_ini_file($file, true, INI_SCANNER_RAW) ?: [];
$this->set($env);
//tp6\vendor\topthink\framework\src\think\Env->set
if (is_array($env)) {
//更改数组中所有键的大小写
$env = array_change_key_case($env, CASE_UPPER);
foreach ($env as $key => $val) {
if (is_array($val)) {
foreach ($val as $k => $v) {
//使字符串大写
$this->data[$key . '_' . strtoupper($k)] = $v;
}
} else {
$this->data[$key] = $val;
}
}
} else {
$name = strtoupper(str_replace('.', '_', $env));
$this->data[$name] = $value;
}
11.加载全局公共文件、系统助手函数、全局配置文件、全局事件定义和全局服务定义
//tp6\vendor\topthink\framework\src\think\App->initialize
$this->load();
//tp6\vendor\topthink\framework\src\think\App->load
$appPath = $this->getAppPath();
if (is_file($appPath . 'common.php')) {
//加载全局公共文件
include_once $appPath . 'common.php';
}
//系统助手函数
include_once $this->thinkPath . 'helper.php';
$configPath = $this->getConfigPath();
$files = [];
//如果文件名存在并且是目录,则为true,否则为false。
if (is_dir($configPath)) {
// 查找与模式匹配的路径名
$files = glob($configPath . '*' . $this->configExt);
}
foreach ($files as $file) {
//全局配置文件
$this->config->load($file, pathinfo($file, PATHINFO_FILENAME));
}
if (is_file($appPath . 'event.php')) {
//全局事件定义
$this->loadEvent(include $appPath . 'event.php');
}
if (is_file($appPath . 'service.php')) {
$services = include $appPath . 'service.php';
foreach ($services as $service) {
//全局服务定义
$this->register($service);
}
}
12.判断应用模式(调试或者部署模式)
//tp6\vendor\topthink\framework\src\think\App->initialize
$this->debugModeInit();
//tp6\vendor\topthink\framework\src\think\App->debugModeInit
// 应用调试模式
if (!$this->appDebug) {
$this->appDebug = $this->env->get('app_debug') ? true : false;
//设置配置选项的值
ini_set('display_errors', 'Off');
}
//是否运行在命令行下
//返回输出缓冲机制的嵌套级别
if (!$this->runningInConsole()) {
//重新申请一块比较大的buffer
if (ob_get_level() > 0) {
//获取当前缓冲区内容并删除当前输出缓冲区
$output = ob_get_clean();
}
//打开输出缓冲
ob_start();
if (!empty($output)) {
echo $output;
}
}
13.监听AppInit
事件
//tp6\vendor\topthink\framework\src\think\App->initialize
$this->event->trigger(AppInit::class);
/**
* AppInit事件类
*/
class AppInit
{}
14.注册异常处理 15.服务注册 16.启动注册的服务
//tp6\vendor\topthink\framework\src\think\App->initialize
foreach ($this->initializers as $initializer) {
//注册异常处理 服务注册 启动注册的服务
$this->make($initializer)->init($this);
}
protected $initializers = [
Error::class,
RegisterService::class,
BootService::class,
];
17. 加载全局中间件定义
//tp6\vendor\topthink\framework\src\think\Http->runWithRequest
$this->loadMiddleware();
protected function loadMiddleware(): void
{
if (is_file($this->app->getBasePath() . 'middleware.php')) {
$this->app->middleware->import(include $this->app->getBasePath() . 'middleware.php');
}
}
18.监听HttpRun
事件
//tp6\vendor\topthink\framework\src\think\Http->runWithRequest
$this->app->event->trigger(HttpRun::class);
/**
* HttpRun事件类
*/
class HttpRun
{}
19.执行全局中间件
//tp6\vendor\topthink\framework\src\think\Http->runWithRequest
//会返回一个 think\response\Html 对象
return $this->app->middleware->pipeline()
->send($request)
->then(function ($request) {
return $this->dispatchToRoute($request);
});
//tp6\vendor\topthink\framework\src\think\Middleware->pipeline
/**
* 调度管道
* @access public
* @param string $type 中间件类型
* @return Pipeline
*/
public function pipeline(string $type = 'global')
{
return (new Pipeline())
->through(array_map(function ($middleware) {
return function ($request, $next) use ($middleware) {
[$call, $params] = $middleware;
if (is_array($call) && is_string($call[0])) {
$call = [$this->app->make($call[0]), $call[1]];
}
//调用第一个参数给出的回调
$response = call_user_func($call, $request, $next, ...$params);
if (!$response instanceof Response) {
throw new LogicException('The middleware must return Response instance');
}
return $response;
};
//中间件排序
}, $this->sortMiddleware($this->queue[$type] ?? [])))
//设置异常处理器
->whenException([$this, 'handleException']);
}