ThinkPHP源码解读1
1.Thinkphp我們可以設置一個入口文件index.php,然后在入口文件中引入Thinkphp框架的入口文件,原則上項目的入口文件可以放到任意處;
2. ThinkPHP框架的入口文件大概做兩個事情,一是定義目錄的常量,二是啟動核心類think的start方法;
3.TP框架的大部分初始化都是在start方法中進行的;一個重要的步驟是加載核心文件,加載哪些文件呢?可以通過自己配置(/Application/Common/Conf/core.php),也可以用默認的方式(ThinkPHP/Mode/common.php");得到數(shù)組,遍歷加載進來就是了;
4.只有加載進來這些核心文件,我們才能用框架定義的函數(shù)A,C,D,數(shù)據(jù)庫類,控制器類等等。
5.繼續(xù)執(zhí)行app類(ThinkPHP/Library/Think/App.class.php)的run方法,這個類上一步已經(jīng)加載進來了
.
5.1 Hook::listen(‘a(chǎn)pp_init’)會執(zhí)行app_init標簽綁定的behavior的run方法,我們可以通過配置來自己實現(xiàn)這個run方法,可以查看https://blog.csdn.net/littlexiaoshuishui/article/details/93741742;App::init();先動態(tài)加載項目公共目錄下的文件(/Application/Common/),load_ext_file(Application/Common),會把目錄里面的配置了外部文件加載進來,例如在/Application/Common/配置db.php,用作數(shù)據(jù)庫的配置文件。
這種配置多個配置文件的原理就是,在/Application/Common/config中配置‘LOAD_EXT_CONFIG’=>‘db‘, 多個配置文件就用逗號隔開,就能加載common/business.php, common/db.php
5.2? App::init() 也調(diào)用Dispatcher::dispatch()做url調(diào)度
thinkphp經(jīng)常用了url重新功能,項目根目錄下有.htaccess文件,例如:http://localhost/wxjza/Root/Home/Test/test
<IfModule mod_rewrite.c>Options +FollowSymlinksRewriteEngine OnRewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_FILENAME} !-fRewriteRule ^(.*)$ index.php?s=/$1 [QSA,PT,L] </IfModule>在Dispatcher::dispatch() 中,打印出$_GET['s'] = ?"/Home/Test/test"; 獲取到url路徑中的參數(shù),然后賦值給$_SERVER['PATH_INFO'];
處理PATHINFO信息,獲取路徑后綴給常量__EXT__; 獲取模塊名給MODULE_NAME;
define('__INFO__',trim($_SERVER['PATH_INFO'],'/'));// URL后綴define('__EXT__', strtolower(pathinfo($_SERVER['PATH_INFO'],PATHINFO_EXTENSION)));$_SERVER['PATH_INFO'] = __INFO__; if(!defined('BIND_MODULE') && (!C('URL_ROUTER_ON') || !Route::check())){if (__INFO__ && C('MULTI_MODULE')){ // 獲取模塊名$paths = explode($depr,__INFO__,2);$allowList = C('MODULE_ALLOW_LIST'); // 允許的模塊列表$module = preg_replace('/\.' . __EXT__ . '$/i', '',$paths[0]);if( empty($allowList) || (is_array($allowList) && in_array_case($module, $allowList))){$_GET[$varModule] = $module;$_SERVER['PATH_INFO'] = isset($paths[1])?$paths[1]:'';}}} }// URL常量define('__SELF__',strip_tags($_SERVER[C('URL_REQUEST_URI')]));// 獲取模塊名稱define('MODULE_NAME', defined('BIND_MODULE')? BIND_MODULE : self::getModule($varModule));檢測模塊路徑,加載改模塊下的配置文件,該模塊下在函數(shù)等等
// 檢測模塊是否存在if( MODULE_NAME && (defined('BIND_MODULE') || !in_array_case(MODULE_NAME,C('MODULE_DENY_LIST')) ) && is_dir(APP_PATH.MODULE_NAME)){// 定義當前模塊路徑define('MODULE_PATH', APP_PATH.MODULE_NAME.'/');// 定義當前模塊的模版緩存路徑C('CACHE_PATH',CACHE_PATH.MODULE_NAME.'/');// 定義當前模塊的日志目錄C('LOG_PATH', realpath(LOG_PATH).'/'.MODULE_NAME.'/');// 模塊檢測Hook::listen('module_check');// 加載模塊配置文件if(is_file(MODULE_PATH.'Conf/config'.CONF_EXT))C(load_config(MODULE_PATH.'Conf/config'.CONF_EXT));// 加載應用模式對應的配置文件if('common' != APP_MODE && is_file(MODULE_PATH.'Conf/config_'.APP_MODE.CONF_EXT))C(load_config(MODULE_PATH.'Conf/config_'.APP_MODE.CONF_EXT));// 當前應用狀態(tài)對應的配置文件if(APP_STATUS && is_file(MODULE_PATH.'Conf/'.APP_STATUS.CONF_EXT))C(load_config(MODULE_PATH.'Conf/'.APP_STATUS.CONF_EXT));// 加載模塊別名定義if(is_file(MODULE_PATH.'Conf/alias.php'))Think::addMap(include MODULE_PATH.'Conf/alias.php');// 加載模塊tags文件定義if(is_file(MODULE_PATH.'Conf/tags.php'))Hook::import(include MODULE_PATH.'Conf/tags.php');// 加載模塊函數(shù)文件if(is_file(MODULE_PATH.'Common/function.php'))include MODULE_PATH.'Common/function.php';$urlCase = C('URL_CASE_INSENSITIVE');// 加載模塊的擴展配置文件load_ext_file(MODULE_PATH);}else{E(L('_MODULE_NOT_EXIST_').':'.MODULE_NAME);}然后用類似的方法,獲取到控制器CONTROLLER_NAME,方法ACTION_NAME,還有url的參數(shù)$_GET,此時,url調(diào)度完畢;
5.3??App::init() 最后是過濾$_GET,$_POST,$_REQUEST,過濾的方法是think_filter().還有判斷是否是ajax請求;
// URL調(diào)度Dispatcher::dispatch();if(C('REQUEST_VARS_FILTER')){// 全局安全過濾array_walk_recursive($_GET, 'think_filter');array_walk_recursive($_POST, 'think_filter');array_walk_recursive($_REQUEST, 'think_filter');}// URL調(diào)度結(jié)束標簽Hook::listen('url_dispatch'); define('IS_AJAX', ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') || !empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')])) ? true : false);5.4? 然后是執(zhí)行App::exec();映射需要執(zhí)行的方法,執(zhí)行對應的方法
//執(zhí)行當前操作$method = new \ReflectionMethod($module, $action);最終都是通過php的映射類來調(diào)用我們的控制器方法的;
?
Thinkphp框架啟動的大致流程就是這樣啦。
總結(jié)
以上是生活随笔為你收集整理的ThinkPHP源码解读1的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 青春的味道-宁波山地马拉松赛记
- 下一篇: Android 开机速度优化-----A