百度首页 | 
百度搜藏
快照
(百度和http://x.discuz.net/13759/viewspace-90169的作者无关,不对其内容负责。百度快照谨为网络故障时之索引,不代表被搜索网站的即时页面。)

史上第一强:Discuz!源代码分析系列(1)--common.inc.php - 傷を追憶↗--郭鑫 - SupeSite/X-Space官方站 - Powered by X-Space - Powered by SupeSite

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

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

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

QUOTE:

KB2s1st0
申明下版权:SupeSite/X-Space官方站 q v+B6P h0J|/xm [
1.这里面的每个中文字都是我打的,code部分是引用的,当然我也加了一点注释在里面了。
qnV$j6j02.如果要转载的话请注明

CODE:SupeSite/X-Space官方站w/~D#Ls uf,YW

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

QUOTE:SupeSite/X-Space官方站B3X-c#t%^z](m

CODE:

ago(l!Kw$u0//定义PHP一些环境SupeSite/X-Space官方站-Kp;Za'~a
error_reporting(0);SupeSite/X-Space官方站_:}[$gRXi
set_magic_quotes_runtime(0);SupeSite/X-Space官方站%zZ ~/T7S^
SupeSite/X-Space官方站1[9\OuTR5SE
//设置Discuz开始的时间
^,R}!ZUl"i p0$mtime = explode(' ', microtime());
N;Q-J,~f}Y q!Osz0$discuz_starttime = $mtime[1] + $mtime[0];SupeSite/X-Space官方站Lb e,ID&FU

+e,y6s;W'ci(M:g0//定义一些常量
3C'Q7q$\U0define('SYS_DEBUG', FALSE);
C3aQ:Wz7[3e [.n0define('IN_DISCUZ', TRUE);
.}qI1i1j(jA m)g+{}0define('DISCUZ_ROOT', substr(dirname(__FILE__), 0, -7)); //获得绝对目录
1ckvZu i V0SupeSite/X-Space官方站(L/tlG[1qj
//通用性
EdQ~`0if(PHP_VERSION < '4.1.0') {
4mU J.V;n5D0~ ^5X0        $_GET = &$HTTP_GET_VARS;
a2z{ k6c:h)t0        $_POST = &$HTTP_POST_VARS;
VT Iz%j#`0        $_COOKIE = &$HTTP_COOKIE_VARS;
^ufDAJ F7D/M0        $_SERVER = &$HTTP_SERVER_VARS;SupeSite/X-Space官方站#H%~&`'K"n if
        $_ENV = &$HTTP_ENV_VARS;
w}xT4q0        $_FILES = &$HTTP_POST_FILES;
j:O2zOO+Nr0}
这一段基本上就是设置一下错误报告,把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:SupeSite/X-Space官方站k1m/H T JC7},E0m Zl

CODE:SupeSite/X-Space官方站`&o1a W E$c

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

CODE:SupeSite/X-Space官方站x9K;A tGsW

define('ISROBOT', getrobot());
,nq!@!LBz"DK6R0if(defined('NOROBOT') && ISROBOT) {
0S2d-?G ~6SfZ0        exit(header("HTTP/1.1 403 Forbidden"));
2}wl&Qt"D px { W0}
这里是定义一个ISROBOT常量,看看浏览者是什么东东,比方说如果浏览者是一个robot那么就直接来一个 403 Forbidden了……

CODE:

|q"x'SLy0define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());SupeSite/X-Space官方站 F*S Q:Q%t
isset($_REQUEST['GLOBALS']) && exit('Access Error');SupeSite/X-Space官方站pVXO8@t9u
foreach(array('_COOKIE', '_POST', '_GET') as $_request) {
-]d)h xiwI0A#@)EX{1k0        foreach($$_request as $_key => $_value) {SupeSite/X-Space官方站2BA;Tpe3gL0w-S
                $_key{0} != '_' && $$_key = daddslashes($_value);SupeSite/X-Space官方站:[PL,V6F7D D*OnM
        }
%T'J4G7D sP2R \#ccf0}
d,sf$b5n I!N.aPP0(!MAGIC_QUOTES_GPC) && $_FILES = daddslashes($_FILES);
此处是过滤提交的变量用的,提高安全性的用法。。

CODE:

LtD[ p}a0$charset = $dbcharset = $forumfounders = $metakeywords = $extrahead = '';SupeSite/X-Space官方站o2B%C7fZy*A/F
$plugins = $hooks = $admincp = array();
De|y6X4|$_w0
5A#Xo2}oK)_2P0`vy0require_once DISCUZ_ROOT.'./config.inc.php';SupeSite/X-Space官方站k6PRK!lf$u
SupeSite/X-Space官方站3Gh1F hM.OpP
$_DCOOKIE = $_DSESSION = $_DCACHE = $_DPLUGIN = $advlist = array();SupeSite/X-Space官方站*Y v4bP1r2B~)B$p,g u
SupeSite/X-Space官方站_-F wma)o
$prelength = strlen($cookiepre);
-C,y$Src&[P(t0foreach($_COOKIE as $key => $val) {SupeSite/X-Space官方站c'` Qm @*i(s
        if(substr($key, 0, $prelength) == $cookiepre) {
N;V,G4dWh p#|O4c#u0                $_DCOOKIE[(substr($key, $prelength))] = MAGIC_QUOTES_GPC ? $val : daddslashes($val);
@AE4B s[(Xy(Rd.k0        }
/S)T/w I8Z3cA)a0}
初始化一些变量,然后引用config.inc.php这个配置文件,这样开始初始化程序的一些东西了。接下来的一个循环把$_COOKIE中的东西取出来存到$_DCOOKIE这个数组中。注意:在登陆的时候Discuz会把登陆信息存放到$_COOKIE中去。在下面一段会有取出的代码。

CODE:

,u @9vpyq0unset($prelength, $_request, $_key, $_value);SupeSite/X-Space官方站%m+y0H0| e V+V
$timestamp = time();SupeSite/X-Space官方站J0` x$f,tS7z:d StT
SupeSite/X-Space官方站1o Sk JVDx4^
if($attackevasive) {SupeSite/X-Space官方站#h!vFE}0a-s0K/?
        require_once DISCUZ_ROOT.'./include/security.inc.php';SupeSite/X-Space官方站~RG1y7`5~
}
这一部分是如果是提高安全用的,防一些非法的入侵,include/security.inc.php文件中就是这样一些检查。

CODE:SupeSite/X-Space官方站%G ^6{W k _/E-Y

require_once DISCUZ_ROOT.'./include/db_'.$database.'.class.php';SupeSite/X-Space官方站'Ea(?$[A-L)]

%N"K)F3W+?Q0SupeSite/X-Space官方站o H#u|'Fj
$PHP_SELF = $_SERVER['PHP_SELF'] ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
f.Z'Ir6}Ht0a)@0$SCRIPT_FILENAME = str_replace('\\\\', '/', (isset($_SERVER['PATH_TRANSLATED']) ? $_SERVER['PATH_TRANSLATED'] : $_SERVER['SCRIPT_FILENAME']));SupeSite/X-Space官方站v}:D!b!KZS
$boardurl = 'http://'.$_SERVER['HTTP_HOST'].preg_replace("/\/+(api|archiver|wap)?\/*$/i", '', substr($PHP_SELF, 0, strrpos($PHP_SELF, '/'))).'/';SupeSite/X-Space官方站2C @?K4k t6L

.X.m&a L1p[#XVR){0if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
T;NWK zT0E0        $onlineip = getenv('HTTP_CLIENT_IP');SupeSite/X-Space官方站3IQ*n}7V2Ro'v|.U9v
} elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {SupeSite/X-Space官方站l5u-P8A"JO] G
        $onlineip = getenv('HTTP_X_FORWARDED_FOR');SupeSite/X-Space官方站jW:p ie:]0Lhx0G
} elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {SupeSite/X-Space官方站LX7[!c+gb
        $onlineip = getenv('REMOTE_ADDR');SupeSite/X-Space官方站 |d*o!O]_
} elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {SupeSite/X-Space官方站 Y#v K9qIu p e
        $onlineip = $_SERVER['REMOTE_ADDR'];SupeSite/X-Space官方站A3Q)T.Q{ q Z
}
第一行是把include/db_mysql.class.php引用进来,这个文件是一个数据库的类。我觉得是不是放在这里太早了点?
\9D!] ?*iXoF0然后接下的作用就是得到自身的名称$PHP_SELF,自身的文件名字$SCRIPT_FILENAME,论坛的地址$boardurl,得到浏览者的一些信息,比方说ip地址,浏览器类型等等。SupeSite/X-Space官方站2T4VQdQ^
Section Three:

QUOTE:SupeSite/X-Space官方站 Er2A9bX2?

CODE:SupeSite/X-Space官方站Y Y k d$F8Or0P

preg_match("/[\d\.]{7,15}/", $onlineip, $onlineipmatches);
B'oJ#x X J0$onlineip = $onlineipmatches[0] ? $onlineipmatches[0] : 'unknown';SupeSite/X-Space官方站6q/X.P7[(Aj.`
unset($onlineipmatches);
看看ip是不是点分段,7-15个数字之间,用到了一个正则表达式,

CODE:SupeSite/X-Space官方站$q]i@B"`Q L

$cachelost = (@include DISCUZ_ROOT.'./forumdata/cache/cache_settings.php') ? '' : 'settings';
o.}%ns7Q0e,q H0@extract($_DCACHE['settings']);
这一段是获得./forumdata/cache/cache_settings.php(即缓存下的设置数组,并展开,方面以后的写法

CODE:SupeSite/X-Space官方站k\uU$iH U+@

if($gzipcompress && function_exists('ob_gzhandler') && CURSCRIPT. != 'wap') {
L.Ub h:~0        ob_start('ob_gzhandler');SupeSite/X-Space官方站} ~Q6x*~7t]4mD3E
} else {SupeSite/X-Space官方站M!j8|2x"i2K6Y2L|
        $gzipcompress = 0;SupeSite/X-Space官方站#m*B ygF
        ob_start();
Ix GxG.j0}
检查gzip是不是打开了,打开就用ob_gzhandler,没有就用ob_start。

CODE:SupeSite/X-Space官方站:IR]~eY,om |

if(!empty($loadctrl) && substr(PHP_OS, 0, 3) != 'WIN') {SupeSite/X-Space官方站-thn.]^W3[ s
        if($fp = @fopen('/proc/loadavg', 'r')) {
XB8l7VpHA0                list($loadaverage) = explode(' ', fread($fp, 6));
X3wV ?|(]4i0                fclose($fp);
3P m @'w8O;Po)S0                if($loadaverage > $loadctrl) {SupeSite/X-Space官方站 Xn_%n)\{ B
                        header("HTTP/1.0 503 Service Unavailable");SupeSite/X-Space官方站(?c X"mZeE
                        include DISCUZ_ROOT.'./include/serverbusy.htm';
D+b$c!Vtz TfH5\K0                        exit();SupeSite/X-Space官方站3LUUQJi(m6YX:Ft-V
                }
#[,gM4\"Fi6h0        }SupeSite/X-Space官方站!k@2u*_c
}
看到了熟悉的service unavailable了吧?呵呵,平衡负载用的。

CODE:SupeSite/X-Space官方站j D h%V/c-z j o)G

if(defined('CURSCRIPT') && in_array(CURSCRIPT, array('index', 'forumdisplay', 'viewthread', 'post', 'blog', 'pm', 'topicadmin', 'register', 'archiver'))) {
e$D&VPu0        $cachelost .= (@include DISCUZ_ROOT.'./forumdata/cache/cache_'.CURSCRIPT.'.php') ? '' : ' '.CURSCRIPT;SupeSite/X-Space官方站no1~"{6k?V7nU2_
}
看看是不是index, forumdisplay, viewthread这些文件是不是缓存了,有的话把它装到$cachelost这个变量中。
[ 本帖最后由 郭鑫 于 2007-5-3 14:37 编辑 ]

TAG:

傷を追憶↗--郭鑫 郭鑫 发布于2007-05-03 14:32:59
Section Four:
s`)cw af&l?Discuz! 免费论坛软件

QUOTE:

CODE:

$db = new dbstuff;
$db->connect($dbhost, $dbuser, $dbpw, $dbname, $pconnect);
$dbhost = $dbuser = $dbpw = $dbname = $pconnect = NULL;
好了,这里是初始化一个dbstull类的实例,也就是说前面的include/db_mysql.class.php在这里用上了,所以我觉得那个require_once早了点,放到这里的前面最合适了~!J下面就是连上mysql了,然后把几个配置的变量NULL掉,安全性考虑得真多,武装到牙齿!

CODE:

$sid = daddslashes(($transsidstatus || (defined('CURSCRIPT') && CURSCRIPT == 'wap'))&& (isset($_GET['sid']) || isset($_POST['sid'])) ?
        (isset($_GET['sid']) ? $_GET['sid'] : $_POST['sid']) :
        (isset($_DCOOKIE['sid']) ? $_DCOOKIE['sid'] : ''));
看看是不是后台设置了通过sid传输的那个东东,还有是不是通过wap访问的,还有是不是有sid这个东东在$_GET或$_POST这两个的任何一个中,以上结论都成立的话从GET中获得sid,不成立的话从$_DCOOKIE中获得。

CODE:

$discuz_auth_key = md5($_DCACHE['settings']['authkey'].$_SERVER['HTTP_USER_AGENT']);设置一个$discuz_auth_key,md5加密。。

CODE:

if(isset($_DCOOKIE['auth']) && $_DCOOKIE['auth']) {
        list($discuz_pw, $discuz_secques, $discuz_uid) = daddslashes(explode("\t", authcode($_DCOOKIE['auth'], 'DECODE')), 1);
        if(!is_numeric($discuz_uid) || !$discuz_uid) {
                clearcookies();
        }
} else {
        list($discuz_pw, $discuz_secques, $discuz_uid) = array('', '', 0);
}
这一段是用来检查是不是$_DCOOKIE[‘auth’]存在,如果有的话就把其中存放的东西分别给$discuz_pw, $discuz_secques, $discuz_uid这三个变量,分别对应密码,提示问题和uid。
I3ARq E |d
php,论坛,bbs,免费,软件;a-@$?        P]ns&T

'bw i
X'^,K        g%|
CEPHP|BBS|论坛
Section Five:
#q%Qb9]0`0b^3v&vPHP|BBS|论坛

QUOTE:

CODE:

$newpm = $newpmexists = $sessionexists = $seccode = $bloguid = 0;//初始化变量

$membertablefields = 'm.uid AS discuz_uid, m.username AS discuz_user, m.password AS discuz_pw, m.secques AS discuz_secques,
        m.adminid, m.groupid, m.groupexpiry, m.extgroupids, m.email, m.timeoffset, m.tpp, m.ppp, m.posts, m.digestposts,
        m.oltime, m.pageviews, m.credits, m.extcredits1, m.extcredits2, m.extcredits3, m.extcredits4, m.extcredits5,
        m.extcredits6, m.extcredits7, m.extcredits8, m.timeformat, m.dateformat, m.pmsound, m.sigstatus, m.invisible,
        m.lastvisit, m.lastactivity, m.lastpost, m.newpm, m.accessmasks, m.xspacestatus, m.editormode, m.customshow';
if($sid) {
        if($discuz_uid) {
                $query = $db->query("SELECT s.sid, s.styleid, s.groupid='6' AS ipbanned, s.pageviews AS spageviews, s.lastolupdate, s.seccode, $membertablefields
                        FROM {$tablepre}sessions s, {$tablepre}members m
                        WHERE m.uid=s.uid AND s.sid='$sid' AND CONCAT_WS('.',s.ip1,s.ip2,s.ip3,s.ip4)='$onlineip' AND m.uid='$discuz_uid'
                        AND m.password='$discuz_pw' AND m.secques='$discuz_secques'");
        } else {
                $query = $db->query("SELECT sid, uid AS sessionuid, groupid, groupid='6' AS ipbanned, pageviews AS spageviews, styleid, lastolupdate, seccode
                        FROM {$tablepre}sessions WHERE sid='$sid' AND CONCAT_WS('.',ip1,ip2,ip3,ip4)='$onlineip'");
        }
        if($_DSESSION = $db->fetch_array($query)) {
                $sessionexists = 1;
                if(!empty($_DSESSION['sessionuid'])) {
                        $query = $db->query("SELECT $membertablefields
                                FROM {$tablepre}members m WHERE uid='$_DSESSION[sessionuid]'");
                        $_DSESSION = array_merge($_DSESSION, $db->fetch_array($query));
                }
        } else {
                $query = $db->query("SELECT sid, groupid, groupid='6' AS ipbanned, pageviews AS spageviews, styleid, lastolupdate, seccode
                        FROM {$tablepre}sessions WHERE sid='$sid' AND CONCAT_WS('.',ip1,ip2,ip3,ip4)='$onlineip'");
                if($_DSESSION = $db->fetch_array($query)) {
                        clearcookies();
                        $sessionexists = 1;
                }
        }
}
这一段是有蛮长的,不过看着长不代表它就难,第一行是初始化变量用的(无论何时用变量都要考虑初始化,要不然安全性不值得一提,一个get就完了)
qpX]0D k4eo接下来是判断是不是有sid,有的话就从cdb_session表中取来,然后连接一下cdb_members表取出一些更具体的东西,具体是哪些东西?在$membertablefields这个变量里面已经全面写出来了,对应数据库看吧,不看的话用英语猜猜得出的。。。在这里Discuz标记了一个sessionexist变量,表示这个会员是在线的。

CODE:

if(!$sessionexists) {
        if($discuz_uid) {
                $query = $db->query("SELECT $membertablefields
                        FROM {$tablepre}members m WHERE m.uid='$discuz_uid' AND m.password='$discuz_pw' AND m.secques='$discuz_secques'");
                if(!($_DSESSION = $db->fetch_array($query))) {
                        clearcookies();
                }
        }
要是不存在sid,不存在discuz_uid,那就肯定没有登陆了,清掉cookie,要是有$discuz_uid的话,还是从members表中取出信息存放到$_DSESSION数组中

CODE:

        if(ipbanned($onlineip)) $_DSESSION['ipbanned'] = 1;

        $_DSESSION['sid'] = random(6);
        $_DSESSION['seccode'] = random(6, 1);
}
$_DSESSION['dateformat'] = empty($_DSESSION['dateformat']) ? $_DCACHE['settings']['dateformat'] : $_DSESSION['dateformat'];
$_DSESSION['timeformat'] = empty($_DSESSION['timeformat']) ? $_DCACHE['settings']['timeformat'] : ($_DSESSION['timeformat'] == 1 ? 'h:i A' : 'H:i');
$_DSESSION['timeoffset'] = isset($_DSESSION['timeoffset']) && $_DSESSION['timeoffset'] != 9999 ? $_DSESSION['timeoffset'] : $_DCACHE['settings']['timeoffset'];
这个是判断ip是不是在被阻止的list里,是的话就标记一下,用$_DSESSION[‘ipbanned’]标记的。再把一个随机的sid和seccode写到$_DSESSION数组。然后接下来是把日期,时间,时差写入$_DSESSION这个变量。

CODE:

$membertablefields = '';
@extract($_DSESSION);

$lastvisit = empty($lastvisit) ? $timestamp - 86400 : $lastvisit;
$timenow = array('time' => gmdate("$dateformat $timeformat", $timestamp + 3600 * $timeoffset),
        'offset' => ($timeoffset >= 0 ? ($timeoffset == 0 ? '' : '+'.$timeoffset) : $timeoffset));

if(PHP_VERSION > '5.1') {
        @date_default_timezone_set('Etc/GMT'.($timeoffset > 0 ? '-' : '+').(abs($timeoffset)));
}
又见变量初始化,然后是把$_DESSION给展开,这样方便多了。接下来判断是不是有上次访问的时间,有的话就没事,没有的话就减去24小时。
"a{z2mNfb^&w]
?/nkx.discuz.net
接下来给一个现在的时间,这里有一个时间的问题,所以把时间加上时差乘上3600秒就得到当前时间了。
cgn-g@
L1f
DPHP|BBS|论坛
PHP 5 能处理时差了,所以Discuz在这里也设置了一下,想得真全面!!php,论坛,bbs,免费,软件~/^{1{gA
x.discuz.netc#V        xg(]L
x.discuz.netVoU4~sCn
Section Six:SupeSite/X-Space官方站rmB XkH0^

QUOTE:

CODE:

$accessadd1 = $accessadd2 = $modadd1 = $modadd2 = '';
if(empty($discuz_uid) || empty($discuz_user)) {
        $discuz_user = $extgroupids = '';
        $discuz_uid = $adminid = $posts = $digestposts = $pageviews = $oltime = $invisible
                = $credits = $extcredits1 = $extcredits2 = $extcredits3 = $extcredits4
                = $extcredits5 = $extcredits6 = $extcredits7 = $extcredits8 = 0;
        $groupid = empty($groupid) || $groupid != 6 ? 7 : 6;

} else {
        $discuz_userss = $discuz_user;
        $discuz_user = addslashes($discuz_user);

        if($accessmasks) {
                $accessadd1 = ', a.allowview, a.allowpost, a.allowreply, a.allowgetattach, a.allowpostattach';
                $accessadd2 = "LEFT JOIN {$tablepre}access a ON a.uid='$discuz_uid' AND a.fid=f.fid";
        }

        if($adminid == 3) {
                $modadd1 = ', m.uid AS ismoderator';
                $modadd2 = "LEFT JOIN {$tablepre}moderators m ON m.uid='$discuz_uid' AND m.fid=f.fid";
        }
}

if($errorreport == 2 || ($errorreport == 1 && $adminid > 0)) {
        error_reporting(E_ERROR | E_WARNING | E_PARSE);
}
首先初始化变量,然后看看$discuz_user$和$discuz_user这两个变量是不是存在,不存在的话一系列的变量全部置0(没登陆当然不存在版主权限管理员什么的),存在的话就来两个赋值,这就是为什么在Discuz UserGuide里面说$discuz_userss是没有过滤的,而$discuz_user是过滤掉的,能直接进行数据库操作的。
2~;bq:U*_/z4r&ahU然后看看怎么样设置PHP 的出错级别,注意如果你的管理员的话,Discuz给的是一个更高的错误显示级别!

CODE:

define('FORMHASH', formhash());

$statstatus && require_once DISCUZ_ROOT.'./include/counter.inc.php';

$extra = isset($extra) && @preg_match("/^[&=;a-z0-9]+$/i", $extra) ? $extra : '';
$tpp = intval(empty($_DSESSION['tpp']) ? $topicperpage : $_DSESSION['tpp']);
$ppp = intval(empty($_DSESSION['ppp']) ? $postperpage : $_DSESSION['ppp']);
这一段定义一个form hash,这个是通过global.func.php这个文件中的formhash()函数来的。然后看是不是要等到统计信息,要的话就引用./include/counter.inc.php这个文件,不要的话当然就不引用了。x.discuz.netCK
wUC B*_&Mg

$extra这个东东不知道做嘛用的。。。。
/J1S{*G\if
}0s
$tpp-threads per page每页的帖子数x.discuz.net7u*G        ljX
$ppp-posts per page每页的回复数

CODE:

$rsshead = $navtitle = $navigation = '';


$_DSESSION['groupid'] = $groupid = empty($ipbanned) ? (empty($groupid) ? 7 : intval($groupid)) : 6;
if(!@include DISCUZ_ROOT.'./forumdata/cache/usergroup_'.$groupid.'.php') {
        $query = $db->query("SELECT type FROM {$tablepre}usergroups WHERE groupid='$groupid'");
        $grouptype = $db->result($query, 0);
        if(!empty($grouptype)) {
                $cachelost .= ' usergroup_'.$groupid;
        } else {
                $grouptype = 'member';
        }
}
用来得到用户组的,首先看看是不是缓存中有,没有的话就访问数据库了,有的话当然就用缓存的。。

CODE:

if($passport_status && ($passport_status != 'shopex' || !$passport_shopex)) {
        $passport_forward = rawurlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
        $link_login = $passport_url.$passport_login_url.(strpos($passport_login_url, '?') === FALSE ? '?' : '&').'forward='.$passport_forward;
        $link_logout = $passport_url.$passport_logout_url.(strpos($passport_logout_url, '?') === FALSE ? '?' : '&').'forward='.$passport_forward;
        $link_register = $passport_url.$passport_register_url.(strpos($passport_register_url, '?') === FALSE ? '?' : '&').'forward='.$passport_forward;
} else {
        $link_login = 'logging.php?action=login';
        $link_logout = 'logging.php?action=logout&formhash='.FORMHASH;
        $link_register = 'register.php';
}
Discuz通行证用的。主要就是得到一些应用程序的地址。

CODE:

if($discuz_uid && $_DSESSION) {
        if(!empty($groupexpiry) && $groupexpiry < $timestamp && (!defined('CURSCRIPT') || (CURSCRIPT != 'wap' && CURSCRIPT != 'member'))) {
                dheader("Location: {$boardurl}member.php?action=groupexpiry");
        } elseif($grouptype && $groupid != getgroupid($discuz_uid, array
                (
                'type' => $grouptype,
                'creditshigher' => $groupcreditshigher,
                'creditslower' => $groupcreditslower
                ), $_DSESSION)) {
                @extract($_DSESSION);
                $cachelost .= (@include DISCUZ_ROOT.'./forumdata/cache/usergroup_'.intval($groupid).'.php') ? '' : ' usergroup_'.$groupid;
        }
}
这一段用来判断你的用户组是不是过期了的,如果过期了很不幸,就被告知用户组过期了。接下来如果没有过期的话就再展开一下$_DSESSION,因为此时的$_DSESSION包含了更多的东西了。3VJ
rS$k:W]v
Discuz! 免费论坛软件C8Gz-x#O)G9MX)\:vQU
SupeSite/X-Space官方站!L)l#x['Y4o        fs~*h
Section Seven:
*f)qK:LK!Lx.discuz.net

QUOTE:

CODE:

if(!in_array($adminid, array(1, 2, 3))) {
        $alloweditpost = $alloweditpoll = $allowstickthread = $allowmodpost = $allowdelpost = $allowmassprune
                = $allowrefund = $allowcensorword = $allowviewip = $allowbanip = $allowedituser = $allowmoduser
                = $allowbanuser = $allowpostannounce = $allowviewlog = $disablepostctrl = $supe_allowpushthread = 0;
} elseif(isset($radminid) && $adminid != $radminid && $adminid != $groupid) {
        $cachelost .= (@include DISCUZ_ROOT.'./forumdata/cache/admingroup_'.intval($adminid).'.php') ? '' : ' admingroup_'.$groupid;
}
这里是权限判断,如果你不是admin, moderator, super moderator,那么你的什么权限都没。。。

CODE:

$forum = array();
$auditstatuson = !empty($mod) && $mod == 'edit' && in_array($adminid, array(1, 2, 3)) && $allowmodpost ? true : false;

$tid = isset($tid) && is_numeric($tid) ? $tid : 0;
$fid = isset($fid) && is_numeric($fid) ? $fid : 0;
$typeid = isset($typeid) ? intval($typeid) : 0;

if(!empty($tid) || !empty($fid)) {
        if(empty($tid)) {
                $query = $db->query("SELECT f.fid, f.*, ff.* $accessadd1 $modadd1, f.fid AS fid
                        FROM {$tablepre}forums f
                        LEFT JOIN {$tablepre}forumfields ff ON ff.fid=f.fid $accessadd2 $modadd2
                        WHERE f.fid='$fid'");
                $forum = $db->fetch_array($query);
        } else {
                $query = $db->query("SELECT t.tid, t.closed,".(defined('SQL_ADD_THREAD') ? SQL_ADD_THREAD : '')." f.*, ff.* $accessadd1 $modadd1, f.fid AS fid
                        FROM {$tablepre}threads t
                        INNER JOIN {$tablepre}forums f ON f.fid=t.fid
                        LEFT JOIN {$tablepre}forumfields ff ON ff.fid=f.fid $accessadd2 $modadd2
                        WHERE t.tid='$tid'".($auditstatuson ? '' : " AND t.displayorder>='0'")." LIMIT 1");
                $forum = $db->fetch_array($query);
                $tid = $forum['tid'];
        }

        if($forum) {
                $fid = $forum['fid'];
                $forum['ismoderator'] = !empty($forum['ismoderator']) || $adminid == 1 || $adminid == 2 ? 1 : 0;
                foreach(array('postcredits', 'replycredits', 'threadtypes', 'digestcredits', 'postattachcredits', 'getattachcredits', 'supe_pushsetting') as $key) {
                        $forum[$key] = !empty($forum[$key]) ? unserialize($forum[$key]) : array();
                }
        } else {
                $fid = 0;
        }
}
得到论坛信息用的,如果你是看forumdisplay页面和看viewthread在数据库中执行的东东不是一样的。这样能得到一点性能上的提升。然后往forum这个数组里面写一些东西进去,比方说:发帖子得到的分数,回复得到的分数,帖子分类的类型等…

CODE:

$styleid = intval(!empty($_GET['styleid']) ? $_GET['styleid'] :
                (!empty($_POST['styleid']) ? $_POST['styleid'] :
                (!empty($_DSESSION['styleid']) ? $_DSESSION['styleid'] :
                $_DCACHE['settings']['styleid'])));

$styleid = intval(isset($stylejump[$styleid]) ? $styleid : $_DCACHE['settings']['styleid']);

if(@!include DISCUZ_ROOT.'./forumdata/cache/style_'.intval(!empty($forum['styleid']) ? $forum['styleid'] : $styleid).'.php') {
        $cachelost .= (@include DISCUZ_ROOT.'./forumdata/cache/style_'.($styleid = $_DCACHE['settings']['styleid']).'.php') ? '' : ' style_'.$styleid;
}
这里是得到论坛风格的地方,可以看到第一行的赋值Disuz用尽一切可能得到一个合理的风格styleid,呵呵,然后再来一行,看看是不是你在论坛底部切换了一下风格,有的话就override一下,把这个风格作为你的当前风格。SupeSite/X-Space官方站 X_!B.]V4@j+^
如果没有缓存的话,再往cachelost这个里面写点东西。

CODE:

if($cachelost) {
        require_once DISCUZ_ROOT.'./include/cache.func.php';
        updatecache();
        dexit('Cache List: '.$cachelost.'<br>Caches successfully created, please refresh.');
}
如果cachelost中有东西的话,那么就调用include/cache.func.php,并用这个文件里面定义的updatecache();来更新缓存,并强制访问者刷新论坛,使缓存立即生效。

CODE:

if(!defined('CURSCRIPT') || CURSCRIPT != 'wap') {
        if($nocacheheaders) {
                @dheader("Expires: 0");
                @dheader("Cache-Control: private, post-check=0, pre-check=0, max-age=0", FALSE);
                @dheader("Pragma: no-cache");
        }
        if($headercharset) {
                @dheader('Content-Type: text/html; charset='.$charset);
        }
        if(empty($_DCOOKIE['sid']) || $sid != $_DCOOKIE['sid']) {
                dsetcookie('sid', $sid, 604800);
        }
}
这里是设置网页的header用的,通过判断是不是wap或者是不是有CURSCRIPT这个常量(注:CURSCRIPT代表了当前执行的script,比方说forumdisplay.php中就会有define(‘CURSCRIPT’, ‘forumdisplay’);这样的定义),下一行是说sid过期了,再生成一个,dsetcookie()这个函数是./include/global.func.php这个文件中定义的。

CODE:

if($cronnextrun && $cronnextrun <= $timestamp) {
        require_once DISCUZ_ROOT.'./include/cron.func.php';
        runcron();
}
呵呵,后台的计划任务来了。。。。当然,这种情况是要至少有一个会员访问论坛,如果说没有人访问,你再设置也没有用,PHP的一大痛处,不能自己执行…

CODE:

if(isset($plugins['include']) && is_array($plugins['include'])) {
        foreach($plugins['include'] as $include) {
                if(!$include['adminid'] || ($include['adminid'] && $include['adminid'] >= $adminid)) {
                        @include_once DISCUZ_ROOT.'./plugins/'.$include['script'].'.inc.php';
                }
        }
}
这里的加载一些插件的文件。

CODE:

if((!empty($_DCACHE['advs']) || $globaladvs || $redirectadvs) && !defined('IN_ADMINCP')) {
        require_once DISCUZ_ROOT.'./include/advertisements.inc.php';
}
这里是看看是不是在论坛的cache中有广告的存在(注:$_DCACHE这个数组中存放的是论坛的一些设置之类的缓存),有广告的话就引用广告的文件。

CODE:

if(isset($allowvisit) && $allowvisit == 0 && !(defined('CURSCRIPT') && CURSCRIPT == 'member' && $action == 'groupexpiry')) {
        showmessage('user_banned', NULL, 'HALTED');
} elseif(!((defined('CURSCRIPT') && in_array(CURSCRIPT, array('logging', 'wap', 'seccode'))) || $adminid == 1)) {
        if($bbclosed) {
                clearcookies();
                $closedreason = $db->result($db->query("SELECT value FROM {$tablepre}settings WHERE variable='closedreason'"), 0);
                showmessage($closedreason ? $closedreason : 'board_closed', NULL, 'NOPERM');
        }
        periodscheck('visitbanperiods');
}
论坛的安全访问设置。一个是不允许访问,另一个是访问到了member.php?action=groupexpiry的话,就说用户被ban了。然后就是检查是不是论坛关闭了,可以看也论坛关闭对管理员没有影响。接下来检查是不是禁的时间到了…periodscheck()函数就是这个用的。如果没到是会被showmessage说没有访问权限的,具体看include/global.func.php这个文件中的定义。当然,下一期我就会分析这个文件。

CODE:

if((!empty($fromuid) || !empty($fromuser)) && ($creditspolicy['promotion_visit'] || $creditspolicy['promotion_register'])) {
        require_once DISCUZ_ROOT.'/include/promotion.inc.php';
}
这个当然是推荐注册用的。应该没看错,呵呵。

CODE:

$rssauth = $rssstatus && $discuz_uid ? rawurlencode(authcode("$discuz_uid\t".($fid ? $fid : '')."\t".substr(md5($discuz_pw.$discuz_secques), 0, 8), 'ENCODE', md5($_DCACHE['settings']['authkey']))) : '0';Rss检查
etGx`8w|Discuz! 免费论坛软件
[?!M,Hgphp,论坛,bbs,免费,软件
e9x/D        qv%\b t?I,qPHP|BBS|论坛好了,到此./include/common.inc.php这个文件就分析完了。
J$?!V,j-Vx.discuz.net

nq]C
L&TSupeSite/X-Space官方站
[ 本帖最后由 郭鑫 于 2007-5-22 18:06 编辑 ]
傷を追憶↗--郭鑫 郭鑫 发布于2007-05-03 14:33:27
Placeholder 1 for updating
傷を追憶↗--郭鑫 郭鑫 发布于2007-05-03 14:33:43
Placeholder 2 for updating
supercyf的个人空间 supercyf 发布于2007-05-03 14:57:39
真正的实用技术性教学文章。。支持一个!最好可以置顶 php,论坛,bbs,免费,软件%]7]"H0t@9qQ3O A

2hF:O
O S ~#^0[        cx.discuz.net
PS:期待更多include文件夹下文件分析哦。
ご壞壞〆瀦ㄣ的个人空间 ご壞壞〆瀦ㄣ 发布于2007-05-03 15:04:04
這個好...學習....
考啊考发布于2007-05-03 15:32:31
收藏了。。。。。。。
xinruby02's Space~ xinruby02 发布于2007-05-03 15:36:59
沙发呀
&b,Vqw_Z
JDiscuz! 免费论坛软件
好不容易呢
4i;y!V%d
kVPHP|BBS|论坛
呵呵技术文章
┚嘎嘎┎聖火的个人空间 ┚嘎嘎┎聖火 发布于2007-05-03 22:22:26
太厉害了
大水牛BB的个人空间 大水牛BB 发布于2007-05-03 22:25:22
不错的说x.discuz.netw._*y@F`
学习了.
『 守护空间 』 伊泽浩 发布于2007-05-05 19:01:59
up
etscarecrow发布于2007-05-06 17:09:15
高手..
刪蒢々記憶的个人空间 刪蒢々記憶 发布于2007-05-06 17:12:16

逆雪寒的个人空间 逆雪寒 发布于2007-05-08 13:15:51
呀呀呀~~~太厉害了
dgz168的个人空间 dgz168 发布于2007-05-08 13:28:26
好文章,学习了!
桃子(小敏)的个人空间 桃子(小敏) 发布于2007-05-08 13:32:57
强烈支持,建议置顶
散步的鱼的个人空间 散步的鱼 发布于2007-05-08 14:18:41
官方对这个帖子可能不以为然吧
噢MY嘎发布于2007-05-08 15:06:35
好不容易呢
peN4l^)I!Yox.discuz.net呵呵技术文章
63490794的个人空间 63490794 发布于2007-05-08 15:54:01
学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习学习
香水有毒的个人空间 香水有毒 发布于2007-05-08 16:25:29
不错,学习了
紫色情缘 安笛 发布于2007-05-08 22:50:31

#ef/Y4g0n|'ODMPHP|BBS|论坛$T8G X:O#c
N

在此非常感谢郭鑫的认真研究和热心奉献~~~  谢谢
我来说两句

(可选)

关于作者