/*從今天開始.我會一有時間就對PHPCMS 整站的代碼做一個詳細的分析.目的很簡單.讓大家都能在phpchina 里面得到進步.
謝謝. 代碼講解分析全部是本人.按照本人的知識水平來講解.如果有說得不對的.請指正.也歡迎指正.大家一起進步.謝謝
希望大家支持哦
首先我對 PHPCMS 的 頭程序文件開始講解 : include/common.inc.php 這個文件是程序啟動的核心文件.復制PHP內容到剪貼板PHP代碼:
*/
<?php
/**
代碼講解分析: DreamFight
*/
$mtime = explode(' ', microtime());
$phpcms_starttime = $mtime[1] + $mtime[0];
/**
microtime() 當前 Unix 時間戳以及微秒數。本函數僅在支持 gettimeofday() 系統調用的操作系統下可用。如果調用時不帶可選參數,本函數以 "msec sec" 的格式返回一個字符串,其中 sec 是自 Unix 紀元(0:00:00 January 1, 1970 GMT)起到現在的秒數,msec 是微秒部分。字符串的兩部分都是以秒為單位返回的。
在windows下他的反回結果是這樣的形式:0.70312700 1230216275。
explode(separator,string,limit)函數把字符串分割為數組。
參數 描述
separator 必需。規定在哪里分割字符串。
string 必需。要分割的字符串。
limit 可選。規定所返回的數組元素的最大數目。
前邊這兩行的代碼主要就是計算腳本開始運行的時間。很常見的寫法。最后結算還在程序運行的終點位置。講到了在給各位說。
*/
unset($LANG, $_REQUEST, $HTTP_ENV_VARS, $HTTP_POST_VARS, $HTTP_GET_VARS, $HTTP_POST_FILES, $HTTP_COOKIE_VARS);
/**
把 $HTTP_ENV_VARS $HTTP_POST_VARS 全局變量設置為 NULL 因為php4.1.0以上默認以 $_POST 來替代。unset后防止程序運行在低版本會出現安全等問題。比如變量注入
*/
set_magic_quotes_runtime(0);
/*
在php.ini的配置文件中,有個布爾值的設置,就是magic_quotes_runtime,當它打開時,php的大部分函數自動的給從外部引入的(包括數據庫或者文件)數據中的溢出字符加上反斜線。
% S* i; @; k! D- n" p0 k. {7 Q* ~9 U1 i$ Y& {' d4 R2 ]
當然如果重復給溢出字符加反斜線,那么字符串中就會有多個反斜線,所以這時就要用set_magic_quotes_runtime()與get_magic_quotes_runtime()設置和檢測php.ini文件中magic_quotes_runtime狀態。. i% @5 ]' C N8 W. C4 u8 p
6 a; Y" {6 W' H# _! o h. Z
為了使自己的程序不管服務器是什么設置都能正常執行。可以在程序開始用get_magic_quotes_runtime檢測設置狀態秋決定是否要手工處理,或者在開始(或不需要自動轉義的時候)用set_magic_quotes_runtime(0)關掉。& O* W6
地球人都知道。就是關了字符竄入庫自動轉意 比如 my name is on'x 轉成 my name is on \'x 為了最大的程序性能所以我們關掉吧~哈哈
*/
define('IN_PHPCMS', TRUE);
/**
程序入口標記。為什么需要這個東西呢。就好比你進一個小區,保安大哥哥肯定要你簽字或是掛個鳥牌證明你是從正門進來的。
防止你翻墻進入去偷東西搞破壞。這個入口標記也有這個功能。 在這里定義了一個常量 IN_PHPCMS 為 TRUE ,然后我在其他程序文件里面檢查這個標記。如果不存在或不為真,
那么就基本可以肯定你這個家伙是個小偷來的。 人可能翻墻進入。但程序怎么翻墻呢。只要在php.ini文件里面激活 allow_url_fopen選項,include() 就可以包含 URL 地址了。你想下如果你有個 放密碼的PHP文件。如果給人家include 了以后。你怕不怕。
*/
define('PHPCMS_ROOT', str_replace("\\", '/', substr(dirname(__FILE__), 0, -8)));
/**
dirname(dirname(__FILE__));得到的是文件上一層目錄名.因為common.inc.php是在include文件夾中的,所以dirname(dirname(__FILE__))的反回地址就是:你的phpcms所在的目錄+include,這里它做了substr(dirname(__FILE__), 0, -8))這么個處理,就去掉了include 所以得到的就是你這個phpcms所在機器上的目錄了。
要主意substr(dirname(__FILE__), 0, -8))它所得到的目錄的路徑是是帶\的這樣是在瀏覽器中訪部一到的所在要把所有的\轉成/.
為了程序產品的跨平臺。自動獲取程序的安裝目錄路徑 ,定義為 PHPCMS_ROOT 常量。方便以后程序使用。建議大家都這樣做哦
*/
require PHPCMS_ROOT.'/include/global.func.php';
/**
包含 全局函數 global.func.php 文件。里面放了些程序全局都有需要用的函數.大家看到了吧。 常量 PHPCMS_ROOT 已經發揮作用。 這樣程序給人家發布到了 二級目錄下。也不需要人家手動改整站根目錄路徑了。
自己好好理解下。。。。。
global.func.php這個頁面等后邊用到的時候來一一講解。
*/
$search_arr = array("/ union /i","/ select /i","/ update /i","/ outfile /i","/ or /i");
/**
("/ union /i") 這個是正則的寫法?不懂正則的自己百度找教程來學。 這里不詳細說了
*/
$replace_arr = array(' union ',' select ',' update ',' outfile ',' or ');
/**
看這個意思很明了。 union :連接兩條SQL語句。 outfile : 主要用來導出數據庫資料到其他介質上。
干啥要定義這兩個變量呢? 在 global.func.php 文件(前面已經加載)里面有個函數 strip_sql() 各位可以看下。
function strip_sql($string)
{
global $search_arr,$replace_arr;
return is_array($string) ? array_map('strip_sql', $string) : preg_replace($search_arr, $replace_arr, $string);
}
函數里面定義了這兩個變量為 global全局變量。 那么函數里就可以直接使用了。 先講解下這個函數吧。 顧名思義這個函數是過濾字符竄里面的SQL語句使得關鍵的SQL語句單詞失效。
主要過濾那些SQL語句呢。 主要是這幾個關鍵字: union select update outfile or 等。因為這幾個SQL字是極度容易在$_GET傳輸中給截注.
這個函數寫得實在精妙。 is_array 來判斷 $string 是否為數組。如果 是 就 array_map() 函數來遞歸過濾
當遞歸調用 strip_sql() 以后 is_array()判斷 $string 肯定為假了,因為$string已經不是數組而是字符竄。所以 執行 preg_replace()函數。這個函數很好理解了。就是替換了。
這個函數的作用就是把$_POST中的內容用一個strip_sql的方法來處理,
**/
$_POST = strip_sql($_POST);
$_GET = strip_sql($_GET);
$_COOKIE = strip_sql($_COOKIE);
/**
使用strip_sql()函數來過濾 $_POST $_GET $_COOKIE;
一般不是開源的站。很少過SQL關鍵字過濾。不過這個也是冒很大風險的。
來說一下strip_sql這個函數,它和里邊的array_map函數一起實現了這個函數的遞歸調用,以來實現字符的替換。
**/
unset($search_arr, $replace_arr);
/**
unset 使用過但以后不需要的變量。這個是很好的習慣。第一不會浪費內存。如果變量存了大量的數據字節,而后你的程序是一直不需要用的。那么
就會很浪費內存。拉底程序性能 . 哈哈。真很書面。反正是好習慣我們都要學習的拉。
*/
$magic_quotes_gpc = get_magic_quotes_gpc(); // get_magic_quotes_gpc()檢測gpc是否系統自動轉意。 gpc 是什么呢? GET POST COOKIE 來來去去就這幾個東西羅。會返回 真或假
if(!$magic_quotes_gpc)
{
$_POST = new_addslashes($_POST);
$_GET = new_addslashes($_GET);
}
/**
判斷一下系統是否打開了自動對gpc進行轉意這個選擇。如果是的話,就不需要我們自動轉意了。如果不是那么還是要老百姓的手段。自己動手豐衣足食。
來看下也是在global.func.php 文件里面定義的這個函數: 其實是一個封裝好的php的 addslashes() 函數的函數。PHP都自己有了為什么還要自己封裝成函數呢?
理由很簡單。為了以后的擴展更改容易羅。如果我們一開始就全部用 addslashes() 這個函數來對 ' 進行轉意的話。那么以后隨著程序的發展。我可能想多過濾個 ^ * ( )之類的
那如何是好呢?所以為了以后孩子的成長。我們還是最好封起來吧。 記住:以后有可能會邊的東西。最好都封裝成模塊。函數 。類。 這樣程序的靈活度就上去了。下面我們就來品一下
這個函數。
function new_addslashes($string)
{
if(!is_array($string)) return addslashes($string);
foreach($string as $key => $val) $string[$key] = new_addslashes($val);
return $string;
}
首先判斷是不是數組,如果不是那么把該值用作addslashes()的參數,進行轉意,并返回。
如果是數組那么一次取出該數組中的值來讓它轉意。
這個函數也是寫得賊好。也是同時考慮過濾 字符竄或數組,也是使用了 傳歸。看下就應該明白了吧。這個不用說了。我們要學下這個思路這個方法方式哦。這樣才能進
*/