[TOC]
* * * * *
#1 啟動概述
* 啟動的總流程按照文件分為三步
* 1 請求入口(public/index.php)
* 2 框架啟動(thinkphp/start.php)
* 3 應用啟動 (thinkphp/library/App.php)
#2 入口文件(public/index.php)
~~~
// 定義應用目錄
define('APP_PATH', __DIR__ . '/../application/');
// 加載框架引導文件
require __DIR__ . '/../thinkphp/start.php';
~~~
> 默認的入口文件在public/index.php
>> 主要定義應用目錄,加載框架引導文件(thinkphp/start.php)
#3 框架啟動(thinkphp/start.php)
## 3-1 框架引導(thinkphp/start.php)
~~~
// 加載基礎文件
require __DIR__ . '/base.php';
// 執行應用
App::run()->send();
~~~
> 框架引導文件(thinkphp/start.php)
>>主要用來啟動框架
>>按照涉及的文件分為以下三步
>>1 定義全局變量與注冊自動加載
>>2 加載默認配置
>>3 啟動應用
## 3-2 定義全局常量(thinkphp/base.php)
~~~
define('THINK_VERSION', '5.0.0');
define('THINK_START_TIME', microtime(true));
define('THINK_START_MEM', memory_get_usage());
define('EXT', '.php');
define('DS', DIRECTORY_SEPARATOR);
defined('THINK_PATH') or define('THINK_PATH', __DIR__ . DS);
define('LIB_PATH', THINK_PATH . 'library' . DS);
define('CORE_PATH', LIB_PATH . 'think' . DS);
define('TRAIT_PATH', LIB_PATH . 'traits' . DS);
defined('APP_PATH') or define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']) . DS);
defined('ROOT_PATH') or define('ROOT_PATH', dirname(APP_PATH) . DS);
defined('EXTEND_PATH') or define('EXTEND_PATH', ROOT_PATH . 'extend' . DS);
defined('VENDOR_PATH') or define('VENDOR_PATH', ROOT_PATH . 'vendor' . DS);
defined('RUNTIME_PATH') or define('RUNTIME_PATH', ROOT_PATH . 'runtime' . DS);
defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH . 'log' . DS);
defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH . 'cache' . DS);
defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'temp' . DS);
defined('CONF_PATH') or define('CONF_PATH', APP_PATH); // 配置文件目錄
defined('CONF_EXT') or define('CONF_EXT', EXT); // 配置文件后綴
defined('ENV_PREFIX') or define('ENV_PREFIX', 'PHP_'); // 環境變量的配置前綴
// 環境常量
define('IS_CLI', PHP_SAPI == 'cli' ? true : false);
define('IS_WIN', strpos(PHP_OS, 'WIN') !== false);
~~~
>>基礎文件(thinkphp/base.php)
>>開始部分定義了框架的全局常量
>>包括框架的運行信息,目錄組織,運行環境等
## 3-3 注冊自動加載(thinkphp/base.php)
~~~
// 載入Loader類
require CORE_PATH . 'Loader.php';
// 加載環境變量配置文件
if (is_file(ROOT_PATH . '.env')) {
$env = parse_ini_file(ROOT_PATH . '.env', true);
foreach ($env as $key => $val) {
$name = ENV_PREFIX . strtoupper($key);
if (is_array($val)) {
foreach ($val as $k => $v) {
$item = $name . '_' . strtoupper($k);
putenv("$item=$v");
}
} else {
putenv("$name=$val");
}
}
}
// 注冊自動加載
\think\Loader::register();
// 注冊錯誤和異常處理機制
\think\Error::register();
~~~
>> 基礎文件(thinkphp/base.php)
>> 中間部分加載環境配置,
>> 啟動自動加載
>> 注冊自定義錯誤與異常處理
## 3-4 加載框架默認配置(thinkphp/convention.php)
~~~
\think\Config::set(include THINK_PATH . 'convention' . EXT);
~~~
>>基礎文件(thinkphp/base.php)
>>最后加載框架默認配置
## 3-5 框架默認配置(thinkphp/convention.php)
~~~
應用設置
模塊設置
URL設置
模板設置
異常及錯誤設置
日志設置
Trace設置
緩存設置
會話設置
Cookie設置
數據庫設置
分頁配置
~~~
>>以數組形式實現框架默認配置
>>相關配置信息可以在應用目錄(application/)中進行覆蓋
#4 應用啟動(thinkphp/library/App.php)
## 4-1 請求分析(App.php->run())
~~~
App.php;
public static function run(Request $request = null)
is_null($request) && $request = Request::instance();
$config = self::initCommon();
if (defined('BIND_MODULE')) {
// 模塊/控制器綁定
BIND_MODULE && Route::bind(BIND_MODULE);
} elseif ($config['auto_bind_module']) {
// 入口自動綁定
$name = pathinfo($request->baseFile(), PATHINFO_FILENAME);
if ($name && 'index' != $name && is_dir(APP_PATH . $name)) {
Route::bind($name);
}
}
$request->filter($config['default_filter']);
。。。。。。
}
~~~
>> 應用啟動的請求分析
>> 首先 創建請求對象(Request)
>> 然后 解析請求的模塊信息
>> 最后 過濾請求信息
## 4-2 應用調度(App.php->run())
~~~
App.php;
public static function run(Request $request = null)
。。。。。。
try {
// 開啟多語言機制
if ($config['lang_switch_on']) {
// 獲取當前語言
$request->langset(Lang::detect());
// 加載系統語言包
Lang::load(THINK_PATH . 'lang' . DS . $request->langset() . EXT);
if (!$config['app_multi_module']) {
Lang::load(APP_PATH . 'lang' . DS . $request->langset() . EXT);
}
}
// 獲取應用調度信息
$dispatch = self::$dispatch;
if (empty($dispatch)) {
// 進行URL路由檢測
$dispatch = self::routeCheck($request, $config);
}
// 記錄當前調度信息
$request->dispatch($dispatch);
// 記錄路由和請求信息
if (self::$debug) {
Log::record('[ ROUTE ] ' . var_export($dispatch, true), 'info');
Log::record('[ HEADER ] ' . var_export($request->header(), true), 'info');
Log::record('[ PARAM ] ' . var_export($request->param(), true), 'info');
}
// 監聽app_begin
Hook::listen('app_begin', $dispatch);
switch ($dispatch['type']) {
case 'redirect':
// 執行重定向跳轉
$data = Response::create($dispatch['url'], 'redirect')->code($dispatch['status']);
break;
case 'module':
// 模塊/控制器/操作
$data = self::module($dispatch['module'], $config, isset($dispatch['convert']) ? $dispatch['convert'] : null);
break;
case 'controller':
// 執行控制器操作
$data = Loader::action($dispatch['controller']);
break;
case 'method':
// 執行回調方法
$data = self::invokeMethod($dispatch['method']);
break;
case 'function':
// 執行閉包
$data = self::invokeFunction($dispatch['function']);
break;
case 'response':
$data = $dispatch['response'];
break;
default:
throw new \InvalidArgumentException('dispatch type not support');
}
} catch (HttpResponseException $exception) {
$data = $exception->getResponse();
}
。。。。。。
}
~~~
>>應用啟動的應用調度
>>首先 檢查語言配置
>>然后 路由解析獲取調度信息
>>最后 根據調度類型執行不同類型應用
## 4-3 數據輸出(App.php->run())
~~~
App.php;
public static function run(Request $request = null)
// 清空類的實例化
Loader::clearInstance();
// 輸出數據到客戶端
if ($data instanceof Response) {
$response = $data;
} elseif (!is_null($data)) {
// 默認自動識別響應輸出類型
$isAjax = $request->isAjax();
$type = $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type');
$response = Response::create($data, $type);
} else {
$response = Response::create();
}
// 監聽app_end
Hook::listen('app_end', $response);
return $response;
。。。。。。
}
~~~
>>應用邏輯執行完后,
>>首先 清空應用執行過程創建的對象
>>然后 根據應用執行后返回的數據創建響應對象(Response)
>>最后 調用相應對象的send()輸出數據到客戶端(start.php文件中)
- 框架簡介
- 簡介
- 框架目錄
- 根目錄
- 應用目錄
- 核心目錄
- 擴展目錄
- 其他目錄
- 框架流程
- 啟動流程
- 請求流程
- 響應流程
- 框架結構
- 應用組織
- 網絡請求
- 路由組織
- 數據驗證
- 數據模型(M)
- 數據庫連接(Connection)
- 數據庫(Db)
- 查詢構造(Builder)
- 數據庫查詢(Query)
- 模型(Model)
- 模板視圖(V)
- 視圖(View)
- 模板引擎(Think)
- 模板標簽庫(TagLib)
- 控制器(C)
- 網絡響應
- 配置與緩存
- 配置操作
- 緩存操作
- cookie與session
- Cookie操作
- Session操作
- 自動加載
- 鉤子注冊
- 文件上傳
- 分頁控制
- 控制臺
- 自動構建
- 日志異常調試
- 異常處理
- 代碼調試
- 日志記錄
- 框架使用
- 1 環境搭建(Server)
- 2 網絡請求(Request)
- 3 請求路由(Route)
- 4 響應輸出(Response)
- 5 業務處理(Controller)
- 6 數據存取(Model)
- 7 Web界面(View)