ThinkPHP控制器,執行流程.
我們對用戶的第一次URL訪問 http:///My/index.php/Index/show/ 所執行的流程進行詳細的分析,用戶的URL訪問首先是定位到了My項目的index.php 入口文件(注意:如果使用了URL_REWRITE,可能index.php已經被隱藏了),項目的入口文件所做的其實是實例化一個App應用實例,并且執行這個應用。http://servername/appName/moduleName/actionName/params
來獲取當前需要執行的項目(appName)、模塊(moduleName)和操作(actionName),在某些情況下,appName可以不需要(通常是網站的首頁,因為項目名稱可以在入口文件中指定,這種情況下,appName就會被入口文件替代)
每個模塊名稱是一個Action文件,類似于我們平常所說的控制器,系統會自動尋找項目類庫Action目錄下面的相關類,如果沒有找到,會嘗試搜索應用目錄下面的組件類中包含的模塊類,如果依然沒有,則拋出異常。
而actionName操作是首先判斷是否存在Action類的公共方法,如果不存在則會繼續尋找父類中的方法,如果依然不存在,則會檢查是否存在空操作定義,如果還沒有就會尋找是否存在自動匹配的模版文件。如果存在模版文件,那么就直接渲染模版輸出。
因此應用開發中的一個重要過程就是給不同的模塊定義具體的操作。一個應用如果不需要和數據庫交互的時候可以不需要定義模型類,但是必須定義Action控制器。
Action控制器的定義非常簡單,只要繼承Action基礎類就可以了,例如:http://servername/index.php/User/
http://servername/index.php/User/add
如果你需要增加或者重新定義自己的操作方法,增加一個方法就可以了,例如http://servername/index.php/User/select/了,系統會自動定位當前操作的模板文件。
默認模塊和操作
http://serverName/index.php,沒有帶任何模塊和操作的參數,系統就會尋找默認模塊和默認操作,通過 DEFAULT_MODULE和DEFAULT_ACTION來定義,系統的默認模塊設置是Index模塊,默認操作設置是index操作。也就是說
http://serverName/index.php和
http://serverName/index.php/Index以及
http://serverName/index.php/Index/index 等效。
入口文件
1、加載公共入口文件
在實例化App類之前,我們需要首先加載系統的公共入口文件ThinkPHP.php,這個文件是ThinkPHP的總入口,讓我們來一探究竟。在加載ThinkPHP.php文件的過程中,其實完成了下面的操作:
記錄開始執行時間 $GLOBALS['_beginTime'];
檢測THINK_PATH定義,如果沒有則創建;
檢測項目名稱APP_NAME,如果沒有則按照一定規則自動定義;
檢測項目編譯緩存目錄定義,沒有則取項目的Temp目錄;
加載系統定義文件defines.php和公共函數文件functions.php;
如果項目編譯緩存目錄不存在,則自動創建項目目錄結構;
加載系統核心類庫(包括Base、App、Action、Model、View、ThinkException、Log);
如果PHP版本低于5.2.0則加載兼容函數庫compat.php;
生成核心編譯緩存~runtime.php;
記錄加載文件時間 $GLOBALS['_loadTime'];
2、項目初始化init
在加載完成ThinkPHP的公共入口文件之后,我們就開始執行應用了,而首先應該是初始化App應用。
設定錯誤和異常處理機制(set_error_handler和set_exception_handler);
項目預編譯并載入;
設置時區支持;
Session過濾器檢查;
session初始化;
檢查并加載插件;
URL分析和調度;
獲取當前執行的模塊和操作名;
加載模塊配置文件;
頁面防刷新機制檢查;
語言檢查并讀取對應的語言文件;
模板檢查并定義相關的模板變量;
RBAC權限檢測;
如果開啟靜態寫入則讀取靜態緩存文件;
應用初始化過濾插件 app_init;
記錄應用初始化時間 $GLOBALS['_initTime']
3、項目預編譯
加載系統慣例配置文件convention.php;
加載項目配置文件 config.php;
加載項目公共文件 common.php;
如果是調試模式加載系統調試配置文件 debug.php;
如果定義了項目的調試配置文件則載入 debug.php;
生成項目編譯緩存文件~app.php;
4、URL分析Dispatcher
檢查當前URL模式URL_MODEL;
如果存在$_GET變量,則根據當前的URL模式和設置進行重定向;
進行路由定義檢測;
分析PATH_INFO的URL信息到數組;
把PATH_INFO得到的值和$_GET合并;
5、獲取模塊和操作名
檢查VAR_MODULE變量(包括GET 和POST),如果未定義,則獲取默認模塊名;
檢查組件模塊;
檢查模塊偽裝;
檢查VAR_ACTION變量(包括GET 和POST),如果未定義,則獲取默認操作名;
檢查操作鏈;
檢查操作偽裝;
6、 項目執行exec
AUTO_LOAD_CLASS 檢查 如果有則導入公共類;
實例化當前模塊的Action控制器類;
如果Action控制器不存在則檢查空模塊 EmptyAction;
檢查操作鏈,如果有執行操作鏈;
檢查前置操作方法 _before_操作名;
執行模塊的操作方法,調度轉移給Action控制器;
執行后置操作方法 _after_操作名;
執行應用結束過濾器 app_end;
如果開啟日志記錄,寫入錯誤日志.
7、執行控制器的操作
實例化視圖類View;
取得當前控制器名稱;
控制器初始化_initialize;
如果操作方法不存在檢查空操作 _empty;
如果空操作沒有定義則檢查對應的模板文件;
調用模型獲取數據;
渲染視圖進行輸出;
8、調用模型獲取數據find
實例化模型類;
模型初始化 _initialize;
判斷當前模型名稱和對應數據表;
實例化數據庫操作對象;
數據表字段檢測并緩存;
查詢需要的數據;
判斷是否視圖模型;
如果是延時查詢返回ResultIterator對象;
取出數據對象的時候記錄樂觀鎖;
獲取文本字段數據;
獲取關聯數據;
對數據對象自動編碼轉換;
記錄當前數據對象;
返回定義的數據格式(數組或者stdClass對象)
9、輸出視圖
模板變量賦值;
檢測是否是布局輸出;
檢測頁面輸出編碼;
緩存初始化過濾 ob_init;
頁面緩存開啟ob_start;
緩存開啟后執行的過濾;
模版文件名過濾 template_file;
定位當前輸出的模板文件;
模版變量過濾 template_var;
根據不同模版引擎進行處理;
如果是PHP模板引擎,直接載入模板文件;
使用內置模板引擎,檢測緩存有效期;
緩存無效則重新編譯模板文件;
載入模板緩存文件;
獲取并清空緩存;
輸出編碼轉換;
輸出過濾 ob_content;
開啟靜態寫入則寫入靜態文件;
如果輸出則獲取視圖運行時間;
如果是display則渲染模板輸出信息;
開啟頁面Trace則顯示頁面Trace信息;
如果是fetch則返回模板輸出信息;
新聞熱點
疑難解答
圖片精選