过去的时光和未来的不确定…让人生有意义…而现在,却是我们忽略掉的…

史上第一强:Discuz!源代码分析系列(1)--common.inc.php

上一篇 / 下一篇  2007-05-03 14:46:49

查看( 1558 ) / 评论( 96 )
好久没有开始写一篇像样的技术文档了,五一难得有这么多的时间,就早起来写一篇好的文章给大家吧~最近都忙一些自己的事情,没多少机会上网来回答问题,实在抱歉……SupeSite/X-Space官方站U}8?'T+m:h.s
好了,言归正传,这次我打算写一个系列的文章,把Discuz的核心文件的源代码一一分解解释出来,大家都知道Discuz的源代码是很经得起时间的考验的,是众多程序员智慧的结晶,我想大家能借鉴一下也是很不错的,唯一一点不好就是,不是OOP(面向对象)的,我最近看了几个框架(framework),也用了一下,感觉OOP的编程让人热血沸腾,大大提高了开发效率,一个小型论坛的开发的话不用像Discuz 这样写这么这么多的代码,很是不错,不过说到面向对象,当然要看看Java,Jsp 或ASP.NET,前两个看得我郁闷,没看了,只学会了ASP.NET,感觉很不错,比PHP先进多了,针对事件、驱动编程,封装,编译,跨平台,听着就觉得很帅了,很适合大型应用,呵呵,扯远了……

QUOTE:

/Fk~ {z%QT|0
申明下版权:SupeSite/X-Space官方站%T RFDi6?
1.这里面的每个中文字都是我打的,code部分是引用的,当然我也加了一点注释在里面了。SupeSite/X-Space官方站!eU*p7F:S6~&V
2.如果要转载的话请注明

CODE:SupeSite/X-Space官方站}0uY'T2w/]N/^ ?2\d:E

转自[url]www.discuz.net[/url] 作者:郭鑫3.由于我个人的能力有限,写这篇文章没有参考一点资料,甚至连本地环境也没有搭建(遇到了白屏问题),所以难免会有错误的地方,大家发现了的话请跟帖或者联系我吧,我会尽快更正。
第一个文件当然是分析./include/common.inc.php这个文件,这个是Discuz的核心中的核心,基本上每次操作都include到了这个文件,下面就分七段来分析这个文件:SupeSite/X-Space官方站/b]!dJE5WJ

.\8I&{'Lmi2@0Section One:

QUOTE:SupeSite/X-Space官方站8N Fjg"[~6E

CODE:

9X8gwU9rg0//定义PHP一些环境SupeSite/X-Space官方站5q+ZVf y5[a0Rh
error_reporting(0);
^+k Ua5jX"I0set_magic_quotes_runtime(0);
k{GL!?1y2@l0
a9{G wf1H+~_0//设置Discuz开始的时间
1tU7{:Z$L4}o0$mtime = explode(' ', microtime());SupeSite/X-Space官方站%K9TM Q&N`$d#cu0v
$discuz_starttime = $mtime[1] + $mtime[0];
%oRa'E ij.VS)Y)K0SupeSite/X-Space官方站!N2Cu F ?4J
//定义一些常量
$YXx z `[3z0define('SYS_DEBUG', FALSE);SupeSite/X-Space官方站LEW+d-f,mtV7X,e
define('IN_DISCUZ', TRUE);SupeSite/X-Space官方站cq xd'K?B
define('DISCUZ_ROOT', substr(dirname(__FILE__), 0, -7)); //获得绝对目录SupeSite/X-Space官方站mX D*]3D)^

o]u,i)x| h0//通用性
8unU8K(s]0if(PHP_VERSION < '4.1.0') {
]!R7U~$O"y};bDX0        $_GET = &$HTTP_GET_VARS;SupeSite/X-Space官方站Am+P,ol0v$@ abm
        $_POST = &$HTTP_POST_VARS;SupeSite/X-Space官方站:C3\ z5Y#i
        $_COOKIE = &$HTTP_COOKIE_VARS;SupeSite/X-Space官方站7P[!V~)a)zo
        $_SERVER = &$HTTP_SERVER_VARS;
1zW-jz2A9@Zu0        $_ENV = &$HTTP_ENV_VARS;SupeSite/X-Space官方站Jmzsk
        $_FILES = &$HTTP_POST_FILES;SupeSite/X-Space官方站gZ/Eo1B
}
这一段基本上就是设置一下错误报告,把magic_quotes这个sick家伙给关了,然后定一个开始的时间,这样我们在论坛底部看到的Process Time就是通过这个开始的时间和一个结束的时间的差来计算的,然后定义一个IN_DISCUZ为真,这个IN_DISCUZ常量的作用就是在其他inc这样的包含文件中防止被非法引用,一旦没有这个常量的话就出现Access Denied这样的字样然后退出。然后获得Discuz运行的绝对目录。接下来是判断PHP 的版本是4.1 以下还是以上,因为PHP以4.1为一个分界线,在4.1以下以$HTTP_GET_VARS[‘xx’]这样的方式来得到get过来的值,而以后用$_GET来得到get过来的值,这样做的目的是为了无论是什么样的PHP版本,都能用$_GET这样的方式得到,有通用性~!
Section Two:

QUOTE:

&{ ~`&@/T'Tt0

CODE:

M:G.J-Dp0require_once DISCUZ_ROOT.'./include/global.func.php';把include/global.inc.php引用进来,这个文件是Discuz的核心函数文件,包含了Discuz用到的很多通用的函数,可以说它就是一个大的通用函数库。

CODE:SupeSite/X-Space官方站#B|b_'S-]KLG

define('ISROBOT', getrobot());SupeSite/X-Space官方站/S1V_[w*F?*VA\
if(defined('NOROBOT') && ISROBOT) {SupeSite/X-Space官方站xhP/^ s^0pMq
        exit(header("HTTP/1.1 403 Forbidden"));
V^wZ.H-D}(c0}
这里是定义一个ISROBOT常量,看看浏览者是什么东东,比方说如果浏览者是一个robot那么就直接来一个 403 Forbidden了……

CODE:SupeSite/X-Space官方站&C9Hzi0[)u T

define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());
*PL:? W*vh{o0isset($_REQUEST['GLOBALS']) && exit('Access Error');SupeSite/X-Space官方站lxk"\-v)x%br/[
foreach(array('_COOKIE', '_POST', '_GET') as $_request) {
{E H Y? z9p0        foreach($$_request as $_key => $_value) {SupeSite/X-Space官方站+Sd'w/QT%o4V
                $_key{0} != '_' && $$_key = daddslashes($_value);SupeSite/X-Space官方站;| ZQ"Hfc0T K9udY
        }
Y5qY-r?N\h&k r#j0}SupeSite/X-Space官方站@\1F*ew)P|
(!MAGIC_QUOTES_GPC) && $_FILES = daddslashes($_FILES);
此处是过滤提交的变量用的,提高安全性的用法。。

CODE:SupeSite/X-Space官方站[#q [ W3F F$]j-{

$charset = $dbcharset = $forumfounders = $metakeywords = $extrahead = '';
J6Ux4R\{G0$plugins = $hooks = $admincp = array();SupeSite/X-Space官方站"{\w"ALE

#T8|?wk.Y$NV0require_once DISCUZ_ROOT.'./config.inc.php';SupeSite/X-Space官方站 hIsk&?ck6g

&cuQ;B wXI0$_DCOOKIE = $_DSESSION = $_DCACHE = $_DPLUGIN = $advlist = array();SupeSite/X-Space官方站0DwN}-`1|BnW'c4L
SupeSite/X-Space官方站zTx"uhK_
$prelength = strlen($cookiepre);
i~3B!OWPzNs0foreach($_COOKIE as $key => $val) {
}Th"cSA$q0        if(substr($key, 0, $prelength) == $cookiepre) {SupeSite/X-Space官方站+@{&mP6y)}ig L5h
                $_DCOOKIE[(substr($key, $prelength))] = MAGIC_QUOTES_GPC ? $val : daddslashes($val);
'P[#^B9kkC(B0        }SupeSite/X-Space官方站(Vu;lR!AI k
}
初始化一些变量,然后引用config.inc.php这个配置文件,这样开始初始化程序的一些东西了。接下来的一个循环把$_COOKIE中的东西取出来存到$_DCOOKIE这个数组中。注意:在登陆的时候Discuz会把登陆信息存放到$_COOKIE中去。在下面一段会有取出的代码。

CODE:SupeSite/X-Space官方站j*p3_#T3@

unset($prelength, $_request, $_key, $_value);SupeSite/X-Space官方站F0ii.lkK^+r9Wy
$timestamp = time();SupeSite/X-Space官方站2h&w'c6Q#c7MT

^2^8V-O(W$] r(v#I0if($attackevasive) {
F8x1WNg F I0        require_once DISCUZ_ROOT.'./include/security.inc.php';
~b.VZ!CWof*t6m0}
这一部分是如果是提高安全用的,防一些非法的入侵,include/security.inc.php文件中就是这样一些检查。

CODE:

:j)O~#{'x7`0require_once DISCUZ_ROOT.'./include/db_'.$database.'.class.php';SupeSite/X-Space官方站?^'[GR1c
SupeSite/X-Space官方站*~(t x)C;x Y d

8?P%o&t"C2j:@W]$?FF0$PHP_SELF = $_SERVER['PHP_SELF'] ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
o(d;q g,G)H5s0$SCRIPT_FILENAME = str_replace('\\\\', '/', (isset($_SERVER['PATH_TRANSLATED']) ? $_SERVER['PATH_TRANSLATED'] : $_SERVER['SCRIPT_FILENAME']));SupeSite/X-Space官方站S!H&vc2~8S#F
$boardurl = 'http://'.$_SERVER['HTTP_HOST'].preg_replace("/\/+(api|archiver|wap)?\/*$/i", '', substr($PHP_SELF, 0, strrpos($PHP_SELF, '/'))).'/';
4^5HXu9B?0
\mV2?-[}q0if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
'~0] `~r8F)r!S0        $onlineip = getenv('HTTP_CLIENT_IP');SupeSite/X-Space官方站$bZE5Ag8I7nvF
} elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
$@L+`A4f$h&~0        $onlineip = getenv('HTTP_X_FORWARDED_FOR');
4Cqz$qgq]0} elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {SupeSite/X-Space官方站F&\c3b)Ur5Od$J7d
        $onlineip = getenv('REMOTE_ADDR');SupeSite/X-Space官方站$UDXo0dqpV
} elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {SupeSite/X-Space官方站 a%^n~(J SC$y'e3|
        $onlineip = $_SERVER['REMOTE_ADDR'];SupeSite/X-Space官方站&X B7T5tC[
}
第一行是把include/db_mysql.class.php引用进来,这个文件是一个数据库的类。我觉得是不是放在这里太早了点?SupeSite/X-Space官方站)@*|/U*tP#kw/y_
然后接下的作用就是得到自身的名称$PHP_SELF,自身的文件名字$SCRIPT_FILENAME,论坛的地址$boardurl,得到浏览者的一些信息,比方说ip地址,浏览器类型等等。SupeSite/X-Space官方站2Y F)VKp*W1XR M%@%h
Section Three:

QUOTE:

!^ `6cZX L^_0

CODE:

8xw#R;M.H `0preg_match("/[\d\.]{7,15}/", $onlineip, $onlineipmatches);
6x&Qy3}*qzUrr?l0$onlineip = $onlineipmatches[0] ? $onlineipmatches[0] : 'unknown';
y%N{F,Iba'K W^0unset($onlineipmatches);
看看ip是不是点分段,7-15个数字之间,用到了一个正则表达式,

CODE:SupeSite/X-Space官方站A h_ T3\ Y y

$cachelost = (@include DISCUZ_ROOT.'./forumdata/cache/cache_settings.php') ? '' : 'settings';
S K7|#?R\$N1}2\0@extract($_DCACHE['settings']);
这一段是获得./forumdata/cache/cache_settings.php(即缓存下的设置数组,并展开,方面以后的写法

CODE:SupeSite/X-Space官方站;y+_6h?/? g

if($gzipcompress && function_exists('ob_gzhandler') && CURSCRIPT. != 'wap') {SupeSite/X-Space官方站r&z*]9AH6_,@
        ob_start('ob_gzhandler');SupeSite/X-Space官方站*x*K9Tu6| n
} else {SupeSite/X-Space官方站T9O;}^7Y\M0j
        $gzipcompress = 0;
+B8nF|Kkh3n9^ LM0        ob_start();
j[-yz8d3mI.N M6R0}
检查gzip是不是打开了,打开就用ob_gzhandler,没有就用ob_start。

CODE:

8XX k-CdG0if(!empty($loadctrl) && substr(PHP_OS, 0, 3) != 'WIN') {SupeSite/X-Space官方站ta7F7sN'i\#_Gr
        if($fp = @fopen('/proc/loadavg', 'r')) {
;f[El,n8X#a;|2m0                list($loadaverage) = explode(' ', fread($fp, 6));SupeSite/X-Space官方站/}0Q cT9H([
                fclose($fp);SupeSite/X-Space官方站wEm.V1LN"U M7GV
                if($loadaverage > $loadctrl) {
D qS-Y:Q0                        header("HTTP/1.0 503 Service Unavailable");
$u{omxK0                        include DISCUZ_ROOT.'./include/serverbusy.htm';SupeSite/X-Space官方站'D[6a.r'RI
                        exit();SupeSite/X-Space官方站Y2J9r-i'kf
                }
/J@$i |#C7W:CF8I H0        }
-k$H$ivZ:\;rBv2x0}
看到了熟悉的service unavailable了吧?呵呵,平衡负载用的。

CODE:

0k;v3J[ Nu.p0if(defined('CURSCRIPT') && in_array(CURSCRIPT, array('index', 'forumdisplay', 'viewthread', 'post', 'blog', 'pm', 'topicadmin', 'register', 'archiver'))) {SupeSite/X-Space官方站}/a*v!vH&@K
        $cachelost .= (@include DISCUZ_ROOT.'./forumdata/cache/cache_'.CURSCRIPT.'.php') ? '' : ' '.CURSCRIPT;SupeSite/X-Space官方站1f$v Ae Q ?+N g-K
}
看看是不是index, forumdisplay, viewthread这些文件是不是缓存了,有的话把它装到$cachelost这个变量中。
[ 本帖最后由 郭鑫 于 2007-5-3 14:37 编辑 ]

TAG:

我来说两句

(可选)

数据统计

  • 访问量: 14778
  • 日志数: 12
  • 图片数: 2
  • 建立时间: 2006-09-22
  • 更新时间: 2007-05-03

RSS订阅

Open Toolbar