Thinkphp源碼分析系列(一)–入口文件


正如官方文檔上所介紹的,thinkphp使用單一入口,所有的請求都從默認的index.php文件進入。當然不是說一定非得從index.php進入,這應該取決於你的服務器配置,一般服務器都會有默認的首頁,比如index.php,index.html,所以一般訪問域名都會先默認訪問上述文件,你還可以創建多個應用,一個應用對應一個入口文件,所有的入口文件都引用一套thinkphp類庫。

我們來看index.php都干了些什么.  index.php主要任務是定義應用名稱和引用類庫路徑。當然也可以定義一些其他的系統常量。

// 檢測PHP環境
if(version_compare(PHP_VERSION,'5.3.0','<')) die('require PHP > 5.3.0 !');

// 開啟調試模式 建議開發階段開啟 部署階段注釋或者設為false
define('APP_DEBUG',True);

// 定義應用目錄
define('APP_PATH','./test/');

// 引入ThinkPHP入口文件
require './ThinkPHP/ThinkPHP.php';

thinkphp官方建議在實際部署應用的時候,我們建議除了應用入口文件和Public資源目錄外,其他文件都放到非WEB目錄下面,具有更好的安全性。

接下來就應該是ThinkPHP.php文件,這個文件主要是用於框架環境的一些設置,包括常用路徑,版本檢測,系統信息等。

<?php
 
// 記錄開始運行時間
$GLOBALS['_beginTime'] = microtime(TRUE);
// 記錄內存初始使用
define('MEMORY_LIMIT_ON',function_exists('memory_get_usage'));
if(MEMORY_LIMIT_ON) $GLOBALS['_startUseMems'] = memory_get_usage();
 
// 版本信息
const THINK_VERSION = '3.2.2';
 
// URL 模式定義
const URL_COMMON = 0; //普通模式
const URL_PATHINFO = 1; //PATHINFO模式
const URL_REWRITE = 2; //REWRITE模式
const URL_COMPAT = 3; // 兼容模式
 
// 類文件后綴
const EXT = '.class.php';
 
// 系統常量定義
//定義當前入口文件所在的目錄,即thinkphp框架的目錄
defined('THINK_PATH') or define('THINK_PATH', __DIR__.'/');
//定義網站應用所在的目錄。一般來說,在index.php文件中我們會定義一下應用路徑,如果說我們在index.php文件中沒有定義APP_PATH,那么這里就會執行define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']).'/');這里會獲取當前執行腳本的服務器端的絕對路徑。一般是index.php文件所在的目錄。在我的電腦上即D:/phpStudy/WWW/thinkphp/,即網站的根目錄。
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); // 是否調試模式
 
/*
這里定義應用模式。到底什么是應用模式?
thinkphp框架為開發者提供了更改核心框架的機會。我們知道一個php框架的核心是定義一些重要的配置文件,引入一些重要的類庫和函數以及適應當前主機環境的的php配置等。所以我們可以把這些核心中需要引入的文件代碼分離出來,全部定義在一個php配置文件中,這個php配置文件就叫做模式的配置文件。然后我們根據模式不同去引用對應的配置文件,分析配置文件中的配置項,並運行之,從而達到改變框架核心的目的。
就拿最為常用的普通模式來說明。
我們在入口文件中定義了app_mode為common,然后在執行thinkphp的start方法的時候就會去分析定義的模式名稱並且根據模式名稱去mode文件夾下去尋找模式對應的common.php文件,
 // 讀取應用模式
 $mode = include is_file(CONF_PATH.'core.php')?CONF_PATH.'core.php':MODE_PATH.APP_MODE.'.php';
在此文件中定義了用於擴展核心的配置項,在引入了這個文件后,我們可以查看start方法后續就會一一去引入配置項中所定義的各個文件。
與此同時,tp默認支持SAE環境,也就是說官方已經給我們寫好了SAE環境的核心框架擴展的代碼,只帶適當的時候觸發。
*/
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('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', ''); // 配置文件解析方法
 
// 系統信息
/*
在magic_quotes_gpc=On的情況下,如果輸入的數據有
單引號(’)、雙引號(”)、反斜線()與 NUL(NULL 字符)等字符都會被加上反斜線。這些轉義是必須的,如果這個選項為off,那么我們就必須調用addslashes這個函數來為字符串增加轉義。
在php5.4以后就廢除了此特性。所以我們在以后就不要依靠這個特性了。為了使自己的程序不管服務器是什么設置都能正常執行。可以在程序開始用get_magic_quotes_runtime檢測該設置的狀態決定是否要手工處理,或者在開始(或不需要自動轉義的時候)用set_magic_quotes_runtime(0)關掉該設置。
判斷php版本,小於5.4的就手動關掉,定義常量。大於5.4直接定義常量為false。
*/
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{
  define('MAGIC_QUOTES_GPC',false);
}
/*
php判斷解析php服務是由那種服務器軟件,是采用那種協議,PHP_ASPI是一個可以直接使用的常量。
如果是nginx+fastcgi環境,那么它的值是cgi-fcgi
如果是apache環境,那么他的值是apache2handler
如果是命令行的形式,那么它的值是cli
PHP_OS PHP所在的操作系統的名字,例如linux和WIN。
充分理解php的各種運行模式,參看:
http://www.jb51.net/article/37756.htm
http://www.cnblogs.com/liuzhang/p/3929198.html
*/
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_')) {
if(IS_CGI) {
  //CGI/FASTCGI模式下
  $_temp = explode('.php',$_SERVER['PHP_SELF']);
  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類
require CORE_PATH.'Think'.EXT;
// 應用初始化
Think\Think::start();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM