:-: **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核心