請看上一篇:DZ論壇核心代碼分析計劃--install包篇
用了兩天時間才把global.func.php分析完。還打算3天把common.inc.php文件整完,發現又分出來很多文件。所以這一次帖子改變一下策略。先上global.func.php文件的分析吧。。分析得不好。很多東西我沒搞明白到底干嘛用的。。。甚至發現幾個在整個DZ的文件系統中都沒引用的函數。可能是測試函數吧。不過挺好用的。自己拿了放自己的函數包裡了。
因為這個包代碼很多。只把個人重要的仔細分析了每個代碼塊。
在上一個文分析計劃裡,我其實少上兩個文件,一個是DZ論壇全局變量申明表。DZ論壇文件作用表。DZ論壇函數調用處表。
因為分析的東西暫時比較少,所以沒有上上來。等全部搞完再說吧。
學習日記如下:
只更新一部分。。。。還有另一部分。。下午更新上來
以下為引用的內容:
Golbal.func.php
日記時間:2008年10月7日10:37:34
1、 這個文件是常被引用的文件,所以開頭還是采用了慣用的常量判斷法。防止被惡意浏覽器直接打開
2、 加密函數authcode中的加密有多次的md5疊加加密。保證密碼的安全性。在常有的思維中,一般是只加密了一次。而在DZ的加密函數中。加密算法很復雜。分別從md5加密,字符隨機截斷加密,位運算加密和與密匙結合加密。
3、 DZ的字符處理工作非常好。雖然在下載的時候我們會選擇utf-8還是gbk。但是不管是處理字符還是處理數據庫鏈接的時候都是第一考慮字符編碼的地方。在db_mysql.class.php文件的數據庫鏈接上就判斷了格式是什麼。代碼如下
$func = empty($pconnect) ? 'mysql_connect' : 'mysql_pconnect';
//建立一個鏈接給類的屬性link之中。並且在建立鏈接的時候就設定編碼方式是如何的。
if(!$this->link = @$func($dbhost, $dbuser, $dbpw, 1)) {
$halt && $this->halt('Can not connect to MySQL server');
} else {
if($this->version() > '4.1') {
global $charset, $dbcharset;
$dbcharset = $dbcharset2 ? $dbcharset2 : $dbcharset;
$dbcharset = !$dbcharset && in_array(strtolower($charset), array('gbk', 'big5', 'utf-8')) ? str_replace('-', '', $charset) : $dbcharset;
$serverset = $dbcharset ? 'character_set_connection='.$dbcharset.', character_set_results='.$dbcharset.', character_set_client=binary' : '';
$serverset .= $this->version() > '5.0.1' ? ((empty($serverset) ? '' : ',').'sql_mode=\'\'') : '';
$serverset && mysql_query("SET $serverset", $this->link);
}
再在global.func.php文件中的字符串處理也是考慮了字符串的編碼格式問題的。
有個全局變量$charset就是用來設定編碼格式的。Cutstr裡根據這個變量的值來對字符串進行處理。
另,在cutstr()函數裡,在進行截斷之前會將字符串中的特殊字符進行處理。
$string = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string);
在處理截斷之後,再將其還原。
$strcut = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $strcut);
這就能解釋為什麼DZ論壇截斷後的文字依然符合原有的文字格式。
4、 對html代碼格式自定義替換。但這裡要注意一下DZ考慮得很周到。
if(is_array($string)) {
foreach($string as $key => $val) {
$string[$key] = dhtmlspecialchars($val);//如果是數租,遍歷數組再調用自身的這個函數對單個字符處理。
}
判斷如果傳入的字符串是數組呢?恩。按我的想法是,只封裝字符的替換部分。但他這裡封裝得很好。因為我在調用這個函數的時候就不用擔心我傳遞的是什麼格式的字符串了。
5、 將頁面跳轉封裝在了dheader函數裡
6、//典型的減少代碼重復輸入函數。處理好email字符串。只需要emailconv(email地址)就能返回一個已經編碼好的email地址了
function emailconv($email, $tolink = 1) {
$email = str_replace(array('@', '.'), array('@', '.'), $email);
return $tolink ? '<a href="mailto: '.$email.'">'.$email.'</a>': $email;
}
7、//對文件名進行截斷處理,輸入文件名,返回處理後的文件名
function fileext($filename) {
return trim(substr(strrchr($filename, '.'), 1, 10));
}
8、 DZ處理浏覽器直接輸入路徑訪問問題是用的判斷常量法。但是機器人呢?機器人可沒常量。但是php有和自定義常量:$_SERVER['HTTP_USER_AGENT']。這兩個是用來判斷機器人的名稱的。裡面還包含了名字。於是機器人的判斷法如下:
//通過分析調用這個函數的common.inc.php文件。這個函數是用來判斷對機器人的處理方式的。
function getrobot() {
if(!defined('IS_ROBOT')) {
//定義搜索引擎名
$kw_spiders = 'Bot|Crawl|Spider|slurp|sohu-search|lycos|robozilla';
//定義浏覽器種類名
$kw_browsers = 'MSIE|Netscape|Opera|Konqueror|Mozilla';
//判斷是否是這些浏覽器,如果是,則定義IS_ROBOT這個常量為假。反之則判斷蜘蛛是不是上述已經定義好的搜索引擎,如果是則定義IS_ROBOT這個常量為真。如果都不滿足條件,定義IS_ROBOT這個常量為假。
if(preg_match("/($kw_browsers)/i", $_SERVER['HTTP_USER_AGENT'])) {
define('IS_ROBOT', FALSE);
} elseif(preg_match("/($kw_spiders)/i", $_SERVER['HTTP_USER_AGENT'])) {
define('IS_ROBOT', TRUE);
} else {
define('IS_ROBOT', FALSE);
}
}
//返回IS_ROBOT這個常量的值
return IS_ROBOT;
}
在common.inc.php文件裡調用是這樣處理的:
//通過這個常量,不允許機器人隨意訪問這個頁面。
define('IS_ROBOT', getrobot());
if(defined('NOROBOT') && IS_ROBOT) {
exit(header("HTTP/1.1 403 Forbidden"));
}
看回來還是常量法。只是這個常量的值是通過函數getrobot()獲取的。
更新錯誤:這些錯誤是我分析在其調用的地方得知的錯誤。但不可能我發現一點改一點,所以在這裡說明
以下為引用的內容:
checklowerlimit():這個函數是用來檢查積分限制的
謝謝下面這些人的幫助
dongxin1390008說:daddslashes函數是檢查php.ini文件的'MAGIC_QUOTES_GPC選項是否打開,若這個關閉,很容易的可以進行sql注射,若關閉了,則使用addslashes對單引號,# 號進行轉義 2008-10-6 17:33:30更新附件包將此注釋加入