discuz!源码分析.doc_第1页
discuz!源码分析.doc_第2页
discuz!源码分析.doc_第3页
discuz!源码分析.doc_第4页
discuz!源码分析.doc_第5页
已阅读5页,还剩96页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

网站建设 作者:边城浪子discuz!源码分析源代码分析1 第一个文件当然是分析./include/common.inc.php这个文件,这个是Discuz的核心中的核心,基本上每次操作都include到了这个文件,下面就分七段来分析这个文件:Section One:以下内容为程序代码:/定义PHP一些环境error_reporting(0);set_magic_quotes_runtime(0);/设置Discuz开始的时间$mtime = explode( , microtime();$discuz_starttime = $mtime1 + $mtime0;/定义一些常量define(SYS_DEBUG, FALSE);define(IN_DISCUZ, TRUE);define(DISCUZ_ROOT, substr(dirname(_FILE_), 0, -7); /获得绝对目录/通用性if(PHP_VERSION $_value) $_key0 != _ & $_key = daddslashes($_value); (!MAGIC_QUOTES_GPC) & $_FILES = daddslashes($_FILES);此处是过滤提交的变量用的,提高安全性的用法。以下内容为程序代码:$charset = $dbcharset = $forumfounders = $metakeywords = $extrahead = ;$plugins = $hooks = $admincp = array();require_once DISCUZ_ROOT./config.inc.php;$_DCOOKIE = $_DSESSION = $_DCACHE = $_DPLUGIN = $advlist = array();$prelength = strlen($cookiepre);foreach($_COOKIE as $key = $val) if(substr($key, 0, $prelength) = $cookiepre) $_DCOOKIE(substr($key, $prelength) = MAGIC_QUOTES_GPC ? $val : daddslashes($val); 初始化一些变量,然后引用config.inc.php这个配置文件,这样开始初始化程序的一些东西了。接下来的一个循环把$_COOKIE中的东西取出来存到$_DCOOKIE这个数组中。注意:在登陆的时候Discuz会把登陆信息存放到$_COOKIE中去。在下面一段会有取出的代码。以下内容为程序代码:unset($prelength, $_request, $_key, $_value);$timestamp = time();if($attackevasive) require_once DISCUZ_ROOT./include/security.inc.php;这一部分代码是提高安全用的,防一些非法的入侵,include/security.inc.php文件中就是这样一些检查。以下内容为程序代码:require_once DISCUZ_ROOT./include/db_.$database.class.php;$PHP_SELF = $_SERVERPHP_SELF ? $_SERVERPHP_SELF : $_SERVERSCRIPT_NAME;$SCRIPT_FILENAME = str_replace(, /, (isset($_SERVERPATH_TRANSLATED) ? $_SERVERPATH_TRANSLATED : $_SERVERSCRIPT_FILENAME);$boardurl = http:/.$_SERVERHTTP_HOST.preg_replace(/+(api|archiver|wap)?/*$/i, , substr($PHP_SELF, 0, strrpos($PHP_SELF, /)./;if(getenv(HTTP_CLIENT_IP) & strcasecmp(getenv(HTTP_CLIENT_IP), unknown) $onlineip = getenv(HTTP_CLIENT_IP); elseif(getenv(HTTP_X_FORWARDED_FOR) & strcasecmp(getenv(HTTP_X_FORWARDED_FOR), unknown) $onlineip = getenv(HTTP_X_FORWARDED_FOR); elseif(getenv(REMOTE_ADDR) & strcasecmp(getenv(REMOTE_ADDR), unknown) $onlineip = getenv(REMOTE_ADDR); elseif(isset($_SERVERREMOTE_ADDR) & $_SERVERREMOTE_ADDR & strcasecmp($_SERVERREMOTE_ADDR, unknown) $onlineip = $_SERVERREMOTE_ADDR;第一行是把include/db_mysql.class.php引用进来,这个文件是一个数据库的类。我觉得是不是放在这里太早了点?然后接下的作用就是得到自身的名称$PHP_SELF,自身的文件名字$SCRIPT_FILENAME,论坛的地址$boardurl,得到浏览者的一些信息,比方说ip地址,浏览器类型等等。以下内容为程序代码:preg_match(/d.7,15/, $onlineip, $onlineipmatches);$onlineip = $onlineipmatches0 ? $onlineipmatches0 : unknown;unset($onlineipmatches);看看ip是不是点分段,7-15个数字之间,用到了一个正则表达式,以下内容为程序代码:$cachelost = (include DISCUZ_ROOT./forumdata/cache/cache_settings.php) ? : settings;extract($_DCACHEsettings);这一段是获得./forumdata/cache/cache_settings.php(即缓存下的设置数组,并展开,方面以后的写法以下内容为程序代码:if($gzipcompress & function_exists(ob_gzhandler) & CURSCRIPT != wap) ob_start(ob_gzhandler); else $gzipcompress = 0; ob_start();检查gzip是不是打开了,打开就用ob_gzhandler,没有就用ob_start。以下内容为程序代码:if(!empty($loadctrl) & substr(PHP_OS, 0, 3) != WIN) if($fp = fopen(/proc/loadavg, r) list($loadaverage) = explode( , fread($fp, 6); fclose($fp); if($loadaverage $loadctrl) header(HTTP/1.0 503 Service Unavailable); include DISCUZ_ROOT./include/serverbusy.htm; exit(); 看到了熟悉的service unavailable了吧?呵呵,平衡负载用的。以下内容为程序代码:if(defined(CURSCRIPT) & in_array(CURSCRIPT, array(index, forumdisplay, viewthread, post, blog, pm, topicadmin, register, archiver) $cachelost .= (include DISCUZ_ROOT./forumdata/cache/cache_.CURSCRIPT.php) ? : .CURSCRIPT;看看是不是index, forumdisplay, viewthread这些文件是不是缓存了,有的话把它装到$cachelost这个变量中。Section Four:以下内容为程序代码:$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掉,安全性考虑得真多,武装到牙齿! 以下内容为程序代码:$sid = daddslashes($transsidstatus | (defined(CURSCRIPT) & CURSCRIPT = wap)& (isset($_GETsid) | isset($_POSTsid) ? (isset($_GETsid) ? $_GETsid : $_POSTsid) : (isset($_DCOOKIEsid) ? $_DCOOKIEsid : );看看是不是后台设置了通过sid传输的那个东东,还有是不是通过wap访问的,还有是不是有sid这个东东在$_GET或$_POST这两个的任何一个中,以上结论都成立的话从GET中获得sid,不成立的话从$_DCOOKIE中获得。 以下内容为程序代码:$discuz_auth_key = md5($_DCACHEsettingsauthkey.$_SERVERHTTP_USER_AGENT);设置一个$discuz_auth_key,md5加密。以下内容为程序代码:if(isset($_DCOOKIEauth) & $_DCOOKIEauth) list($discuz_pw, $discuz_secques, $discuz_uid) = daddslashes(explode(t, authcode($_DCOOKIEauth, DECODE), 1); if(!is_numeric($discuz_uid) | !$discuz_uid) clearcookies(); else list($discuz_pw, $discuz_secques, $discuz_uid) = array(, , 0);这一段是用来检查是不是$_DCOOKIEauth存在,如果有的话就把其中存放的东西分别给$discuz_pw, $discuz_secques, $discuz_uid这三个变量,分别对应密码,提示问题和uid。Section Five:以下内容为程序代码:$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 $tablepresessions s, $tablepremembers 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 $tablepresessions WHERE sid=$sid AND CONCAT_WS(.,ip1,ip2,ip3,ip4)=$onlineip); if($_DSESSION = $db-fetch_array($query) $sessionexists = 1; if(!empty($_DSESSIONsessionuid) $query = $db-query(SELECT $membertablefields FROM $tablepremembers m WHERE uid=$_DSESSIONsessionuid); $_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 $tablepresessions WHERE sid=$sid AND CONCAT_WS(.,ip1,ip2,ip3,ip4)=$onlineip); if($_DSESSION = $db-fetch_array($query) clearcookies(); $sessionexists = 1; 这一段是有蛮长的,不过看着长不代表它就难,第一行是初始化变量用的(无论何时用变量都要考虑初始化,要不然安全性不值得一提,一个get就完了)接下来是判断是不是有sid,有的话就从cdb_session表中取来,然后连接一下cdb_members表取出一些更具体的东西,具体是哪些东西?在$membertablefields这个变量里面已经全面写出来了,对应数据库看吧,不看的话用英语猜猜得出的。在这里Discuz标记了一个sessionexist变量,表示这个会员是在线的。 以下内容为程序代码:if(!$sessionexists) if($discuz_uid) $query = $db-query(SELECT $membertablefields FROM $tablepremembers 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数组中以下内容为程序代码: if(ipbanned($onlineip) $_DSESSIONipbanned = 1; $_DSESSIONsid = random(6); $_DSESSIONseccode = random(6, 1);$_DSESSIONdateformat = empty($_DSESSIONdateformat) ? $_DCACHEsettingsdateformat : $_DSESSIONdateformat;$_DSESSIONtimeformat = empty($_DSESSIONtimeformat) ? $_DCACHEsettingstimeformat : ($_DSESSIONtimeformat = 1 ? h:i A : H:i);$_DSESSIONtimeoffset = isset($_DSESSIONtimeoffset) & $_DSESSIONtimeoffset != 9999 ? $_DSESSIONtimeoffset : $_DCACHEsettingstimeoffset;这个是判断ip是不是在被阻止的list里,是的话就标记一下,用$_DSESSIONipbanned标记的。再把一个随机的sid和seccode写到$_DSESSION数组。然后接下来是把日期,时间,时差写入$_DSESSION这个变量。 以下内容为程序代码:$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小时。接下来给一个现在的时间,这里有一个时间的问题,所以把时间加上时差乘上3600秒就得到当前时间了。PHP 5 能处理时差了,所以Discuz在这里也设置了一下,想得真全面!Section Six:quote 以下内容为程序代码:$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 $tablepreaccess a ON a.uid=$discuz_uid AND a.fid=f.fid; if($adminid = 3) $modadd1 = , m.uid AS ismoderator; $modadd2 = LEFT JOIN $tablepremoderators 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是过滤掉的,能直接进行数据库操作的。然后看看怎么样设置PHP 的出错级别,注意如果你的管理员的话,Discuz给的是一个更高的错误显示级别! 以下内容为程序代码: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($_DSESSIONtpp) ? $topicperpage : $_DSESSIONtpp);$ppp = intval(empty($_DSESSIONppp) ? $postperpage : $_DSESSIONppp);这一段定义一个form hash,这个是通过global.func.php这个文件中的formhash()函数来的。然后看是不是要等到统计信息,要的话就引用./include/counter.inc.php这个文件,不要的话当然就不引用了。$extra这个东东不知道做嘛用的。$tppthreads per page每页的帖子数$pppposts per page每页的回复数以下内容为程序代码:$rsshead = $navtitle = $navigation = ;$_DSESSIONgroupid = $groupid = empty($ipbanned) ? (empty($groupid) ? 7 : intval($groupid) : 6;if(!include DISCUZ_ROOT./forumdata/cache/usergroup_.$groupid.php) $query = $db-query(SELECT type FROM $tablepreusergroups WHERE groupid=$groupid); $grouptype = $db-result($query, 0); if(!empty($grouptype) $cachelost .= usergroup_.$groupid; else $grouptype = member; 用来得到用户组的,首先看看是不是缓存中有,没有的话就访问数据库了,有的话当然就用缓存的。以下内容为程序代码:if($passport_status & ($passport_status != shopex | !$passport_shopex) $passport_forward = rawurlencode(http:/.$_SERVERHTTP_HOST.$_SERVERREQUEST_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通行证用的。主要就是得到一些应用程序的地址。 以下内容为程序代码:if($discuz_uid & $_DSESSION) if(!empty($groupexpiry) & $groupexpiry $grouptype, creditshigher = $groupcreditshigher, creditslower = $groupcreditslower ), $_DSESSION) extract($_DSESSION); $cachelost .= (include DISCUZ_ROOT./forumdata/cache/usergroup_.intval($groupid).php) ? : usergroup_.$groupid; 这一段用来判断你的用户组是不是过期了的,如果过期了很不幸,就被告知用户组过期了。接下来如果没有过期的话就再展开一下$_DSESSION,因为此时的$_DSESSION包含了更多的东西了。 以下内容为程序代码: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,那么你的什么权限都没。以下内容为程序代码:$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 $tablepreforums f LEFT JOIN $tablepreforumfields 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 $tableprethreads t INNER JOIN $tablepreforums f ON f.fid=t.fid LEFT JOIN $tablepreforumfields 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 = $forumtid; if($forum) $fid = $forumfid; $forumismoderator = !empty($forumismoderator) | $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页面和看viewt

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论