詳細解析Thinkphp5.1源碼執行入口文件index.php運行過程
運行了public目錄下的index.php文件後,tp的運行整個運行過程的解析
入口文件index.php代碼如下:
<?php // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK ] // +---------------------------------------------------------------------- // | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved. // +---------------------------------------------------------------------- // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) // +---------------------------------------------------------------------- // | Author: liu21st <[email protected]> // +---------------------------------------------------------------------- // [ 應用入口文件 ] namespace think; // 加載基礎文件 require __DIR__ . '/../thinkphp/base.php'; // 支持事先使用靜態方法設置Request對象和Config對象 // 執行應用並響應 Container::get('app')->run()->send();
解析:
1. 執行require __DIR__ . '/../thinkphp/base.php'; 引入base.php,實現自動加載機制。自動加載機制的實現過程請看上一篇文章。
2. 重點解析這行代碼:執行Container::get('app')->run()->send(); 通過容器註冊App,並且執行think\App.php的run()方法,將執行到的結果給到think\Response.php的send()響應請求。
具體過程如下:
- 通過容器Container通過反射模式註冊實例化app類
- 調用app類應用程序初始化run方法
- 初始化應用-run()
- 初始化應用-initialize()
- 設置環境變量目錄,如runtime_path、vendor_path、app_path、root_path、route等。-initialize()
- 加載環境變量配置.env-initialize()
- 註冊應用命名空間-initialize()
- 初始化應用-init()
- 找到當前運行模塊
- 判斷緩存配置文件是否存在,存在,則加載初始化文件init.php,不去讀取應用或模塊下的配置文件
- 不存在,則去讀取應用或模塊下的配置文件,如:tags、common、provider、middleware等
- 如果模塊下擁有同樣的配置,那麼模塊下的配置即覆蓋應用下的配置
- 初始化數據庫配置
- 讀取語言包
- 路由初始化
- 路由檢測
- 檢測是否有緩存
- 是否開啓強制路由
- 路由檢測-$this->route->check($path, $must);【此時如果路由找不到,且路由中未定義miss,則在這裏拋出異常。】
- 自動檢測域名路由
- 檢測域名路由
- 檢測域名路由別名
- 檢測URL綁定
- 路由組檢測路由-RuleGroup->check()【一個請求地址遍歷路由文件一個一個匹配,是否匹配中】
- 檢測是否跨域路由設置,是則加跨域,跨域參數加在$this->option變量中
- 檢測路由分組有效性,路由請求是否與路由設置一致,如請求類型、域名、參數等
- 檢測路由前置行爲,並通過容器方式註冊鉤子,並執行行爲。所以,路由中的行爲在路由檢測中就執行了。
- 路由分組檢測think\Route\RouteItem->check();
- 匹配中路由,返回路由分發地址
- 匹配中路由,通過中間件過度執行路由匹配結果,$response = $this->middleware->dispatch($this->request);【如果路由找不到,且路路由中定義了miss,則在這裏跑出miss對應的路由。】
- 如果有綁定中間件,則執行中間件。如果中間件接手返回機制,返回一個response對象,則不會執行路由的分發機制。否則,中間件執行完,執行到return $next($request);的時候,繼續執行路由的分發機制-think\Route\Dispatch。
- 執行路由分發機制-think\Route\Dispatch的時候才執行路由的後置行爲。【路由後置行爲建議使用中間件替代】(來自源碼)
- 執行完run。返回執行結果。【路由分發的執行結果(來自控制器)或中間件的執行結果】
- 執行think\Response的send()響應請求。【注意:如果代碼中自定義了返回機制,且die或exit,則不會走到這一步,則路由中定義的header跨域之類的也因此不會生效,需要自定義header返回處理】