Thinkphp3原始碼分析(2)

codefly發表於2019-03-01

上次分析完了ThinkPHP3的入口檔案(index.php),按照TP3原始碼的檔案載入的順序,今天開始分析path/ThinkPHP/ThinkPHP.php檔案。

為了方便解釋,我直接先將path/ThinkPHP/ThinkPHP.php檔案中的內容先貼上出來(在程式碼中,我會加上自己理解的註釋)。

/----------------------------------
// ThinkPHP公共入口檔案
//----------------------------------

// 記錄開始執行時間
$GLOBALS[`_beginTime`] = microtime(TRUE);

// 記錄記憶體初始使用
define(`MEMORY_LIMIT_ON`,function_exists(`memory_get_usage`));

/*
 * 註釋:memory_get_usage()函式返回當前作業系統分配給當前指令碼的記憶體是多少
 *      隨著指令碼的執行,分配的記憶體的多少是會發生變化的
 * */

if(MEMORY_LIMIT_ON) $GLOBALS[`_startUseMems`] = memory_get_usage();


// 版本資訊
const THINK_VERSION     =   `3.2.3`;

// URL 模式定義
const URL_COMMON        =   0;  //普通模式
const URL_PATHINFO      =   1;  //PATHINFO模式
const URL_REWRITE       =   2;  //REWRITE模式
const URL_COMPAT        =   3;  // 相容模式

// 類檔案字尾
const EXT               =   `.class.php`;  // 檔案字尾名的定義

// 系統常量定義
defined(`THINK_PATH`)   or define(`THINK_PATH`,     __DIR__.`/`);
defined(`APP_PATH`)     or define(`APP_PATH`,       dirname($_SERVER[`SCRIPT_FILENAME`]).`/`);
defined(`APP_STATUS`)   or define(`APP_STATUS`,     ``); // 應用狀態 載入對應的配置檔案
defined(`APP_DEBUG`)    or define(`APP_DEBUG`,      false); // 是否除錯模式

/*
if(function_exists(`saeAutoLoader`)){// 自動識別SAE環境
    defined(`APP_MODE`)     or define(`APP_MODE`,      `sae`);
    defined(`STORAGE_TYPE`) or define(`STORAGE_TYPE`,  `Sae`);
}else{
    defined(`APP_MODE`)     or define(`APP_MODE`,       `common`); // 應用模式 預設為普通模式    
    defined(`STORAGE_TYPE`) or define(`STORAGE_TYPE`,   `File`); // 儲存型別 預設為File    
}
*/

defined(`APP_MODE`)     or define(`APP_MODE`,       `common`); // 應用模式 預設為普通模式
defined(`STORAGE_TYPE`) or define(`STORAGE_TYPE`,   `File`); // 儲存型別 預設為File


/*
 * 執行時目錄?????
 * */
defined(`RUNTIME_PATH`) or define(`RUNTIME_PATH`,   APP_PATH.`Runtime/`);   // 系統執行時目錄


defined(`LIB_PATH`)     or define(`LIB_PATH`,       realpath(THINK_PATH.`Library`).`/`); // 系統核心類庫目錄
defined(`CORE_PATH`)    or define(`CORE_PATH`,      LIB_PATH.`Think/`); // Think類庫目錄
defined(`BEHAVIOR_PATH`)or define(`BEHAVIOR_PATH`,  LIB_PATH.`Behavior/`); // 行為類庫目錄

defined(`MODE_PATH`)    or define(`MODE_PATH`,      THINK_PATH.`Mode/`); // 系統應用模式目錄

defined(`VENDOR_PATH`)  or define(`VENDOR_PATH`,    LIB_PATH.`Vendor/`); // 第三方類庫目錄

defined(`COMMON_PATH`)  or define(`COMMON_PATH`,    APP_PATH.`Common/`); // 應用公共目錄
defined(`CONF_PATH`)    or define(`CONF_PATH`,      COMMON_PATH.`Conf/`); // 應用配置目錄
defined(`LANG_PATH`)    or define(`LANG_PATH`,      COMMON_PATH.`Lang/`); // 應用語言目錄
defined(`HTML_PATH`)    or define(`HTML_PATH`,      APP_PATH.`Html/`); // 應用靜態目錄
defined(`LOG_PATH`)     or define(`LOG_PATH`,       RUNTIME_PATH.`Logs/`); // 應用日誌目錄
defined(`TEMP_PATH`)    or define(`TEMP_PATH`,      RUNTIME_PATH.`Temp/`); // 應用快取目錄


defined(`DATA_PATH`)    or define(`DATA_PATH`,      RUNTIME_PATH.`Data/`); // 應用資料目錄
defined(`CACHE_PATH`)   or define(`CACHE_PATH`,     RUNTIME_PATH.`Cache/`); // 應用模板快取目錄
defined(`CONF_EXT`)     or define(`CONF_EXT`,       `.php`); // 配置檔案字尾
defined(`CONF_PARSE`)   or define(`CONF_PARSE`,     ``);    // 配置檔案解析方法
defined(`ADDON_PATH`)   or define(`ADDON_PATH`,     APP_PATH.`Addon`);


/*
 * define() const() $GLOBALS ----為什麼要用三種定義變數的方式那????
 * define()可以配合defined()來檢測常量是否已經被定義過 const()則是不可以的
 *
 *
 * */


/*
 * 關閉掉php的自動轉義
 * */
if(version_compare(PHP_VERSION,`5.4.0`,`<`)) {
    //關閉掉自動轉義的功能
    ini_set(`magic_quotes_runtime`,0);
    //定義關閉掉自動轉義功能表示常量
    define(`MAGIC_QUOTES_GPC`,get_magic_quotes_gpc()? true : false);
}else{
    //php5.4以後取消了magic_quotes_runtime配置選項,也就說php不再預設進行轉義處理了,如果需要,自行轉義
    define(`MAGIC_QUOTES_GPC`,false);
}

/*
 * 檢測當前執行php指令碼的模式
 * */
define(`IS_CGI`,(0 === strpos(PHP_SAPI,`cgi`) || false !== strpos(PHP_SAPI,`fcgi`)) ? 1 : 0 );
define(`IS_WIN`,strstr(PHP_OS, `WIN`) ? 1 : 0 );
define(`IS_CLI`,PHP_SAPI==`cli`? 1   :   0);


/*
 * 獲取真實訪問的指令碼名稱
 * */

//如果不是命令列模式
if(!IS_CLI) {
    // 當前檔名
    if(!defined(`_PHP_FILE_`)) {
        //如果是CGI的方式
        if(IS_CGI) {
            //CGI/FASTCGI模式下
            $_temp  = explode(`.php`,$_SERVER[`PHP_SELF`]);
            //str_replace(待替換字串,需要替換成的字串,目的字串)
            define(`_PHP_FILE_`,    rtrim(str_replace($_SERVER[`HTTP_HOST`],``,$_temp[0].`.php`),`/`));
        }else {
            define(`_PHP_FILE_`,    rtrim($_SERVER[`SCRIPT_NAME`],`/`));
        }
    }
    if(!defined(`__ROOT__`)) {
        $_root  =   rtrim(dirname(_PHP_FILE_),`/`);
        define(`__ROOT__`,  (($_root==`/` || $_root==`\`)?``:$_root));
    }
}

// 載入核心Think類
//path/ThinkPHP/Library/Think/Think.class.php
require CORE_PATH.`Think`.EXT;
// 應用初始化
ThinkThink::start();複製程式碼

其實這個檔案解釋起來很簡單,沒有什麼特殊寫法,用途也是非常的明顯,主要就是定義框架中需要的一系列的常量,檢測訪問的方式(CGI/FASTCGI/CLI),關閉php中的自動轉義功能 。

TP將設定系統常量,檢測開發環境的操作全都放置在這個檔案中,這樣的好處就是以後程式碼的更新修改起來方便。

相關文章