设为首页 收藏本站
查看: 495|回复: 0

[经验分享] Discuz代码分析——index.php

[复制链接]

尚未签到

发表于 2015-8-28 11:45:49 | 显示全部楼层 |阅读模式
/*  
      [Discuz!] (C)2001-2007 Comsenz Inc.  
      This is NOT a freeware, use is subject to license terms  
      $Id: index.php 13764 2008-05-19 03:14:01Z heyond $  
*/  
define('CURSCRIPT', 'index');//定义当前运行脚本名   
require_once './include/common.inc.php';//引入common文件   
require_once DISCUZ_ROOT.'./include/forum.func.php';//引入版块处理函数forum.func.php   
$discuz_action = 1;//?   
if($cacheindexlife && !$discuz_uid && $showoldetails != 'yes' && (!$_DCACHE['settings']['frameon'] || $_DCACHE['settings']['frameon'] && $_GET['frameon'] != 'yes') && emptyempty($gid)) {   
     //分析:$cacheindexlife-首页缓存有效期,$discuz_uid存在,$showoldetails-显示在线详 情,$_DCACHE['settings']['frameon']-左右分栏模式开关,$gid-版块组id,自己看看吧,大概就是判断是否使用一个 静态htm页面的条件,这个由后台是否开启首页缓存时间来决定的   
      $indexcache = getcacheinfo(0);//得到首页缓存,此函数见include/forum.func.php 157行,主要是处理index.htm   
      //下面一段就是判断是否过期咯,如果过期,就删除index.htm,否则读取文件,并根据系统配置决定是否显示debug信息   
      if($timestamp - $indexcache['filemtime'] > $cacheindexlife) {   
          @unlink($indexcache['filename']);   
          define('CACHE_FILE', $indexcache['filename']);   
          $styleid = $_DCACHE['settings']['styleid'];   
      } elseif($indexcache['filename']) {   
          @readfile($indexcache['filename']);   
          $debug && debuginfo();   
          $debug ? die('<mce:script type="text/javascript"><!--   
document.getElementById("debuginfo").innerHTML = " '.($debug ? 'Updated at '.gmdate("H:i:s", $indexcache['filemtime'] + 3600 * 8).', Processed in '.$debuginfo['time'].' second(s), '.$debuginfo['queries'].' Queries'.($gzipcompress ? ', Gzip enabled' : '') : '').'";   
// --></mce:script>') : die();   
      }   
}   
//$validdays?用户组有效时间?   
$validdays = $discuz_uid && !emptyempty($groupexpiry) && $groupexpiry >= $timestamp ? ceil(($groupexpiry - $timestamp) / 86400) : 0;   
//是否显示在线情况   
if(isset($showoldetails)) {   
      switch($showoldetails) {   
          case 'no': dsetcookie('onlineindex', 0, 86400 * 365); break;   
          case 'yes': dsetcookie('onlineindex', 1, 86400 * 365); break;   
      }   
} else {   
      $showoldetails = false;   
}   
$currenttime = gmdate($timeformat, $timestamp + $timeoffset * 3600);//当前时间   
$lastvisittime = gmdate("$dateformat $timeformat", $lastvisit + $timeoffset * 3600);//上次访问时间   
$memberenc = rawurlencode($lastmember);//最后注册用户-对URL进行了编码   
$newthreads = round(($timestamp - $lastvisit + 600) / 1000) * 1000;//这个变量不知道干啥的?   
$rsshead = $rssstatus ? ('<link rel="alternate" type="application/rss+xml" title="'.$bbname.'" href="'.$boardurl.'rss.php?auth='.$rssauth." mce_href="'.$boardurl.'rss.php?auth='.$rssauth."\" />\n") : '';//rss的链接   
$customtopics = '';   
if($qihoo['maxtopics']) {   
      foreach(explode("\t", isset($_DCOOKIE['customkw']) ? $_DCOOKIE['customkw'] : '') as $topic) {   
          $topic = dhtmlspecialchars(trim(stripslashes($topic)));   
         $customtopics .= '<a href="topic.php?keyword='.rawurlencode($topic).'" mce_href="topic.php?keyword='.rawurlencode($topic).'" target="_blank">'.$topic.'</a> ';   
      }   
}//以上两段,qihoo专题?-后台的扩展-qihoo搜索那里可以设置   
$hottagstatus = $tagstatus && $hottags && $_DCACHE['tags'];//显示热门标签   
$catlist = $forumlist = $sublist = $forumname = $collapseimg = $collapse = array();//初始化区、版块、子版等数组   
$threads = $posts = $todayposts = $fids = $announcepm = 0;//初始化帖子、回复、今日回复、版块id等数组   
$postdata = $historyposts ? explode("\t", $historyposts) : array();//历史发帖?   
foreach(array('forumlinks', 'birthdays') as $key) {//处理友情链接与生日用户的显示   
      if(!isset($_COOKIE['discuz_collapse']) || strpos($_COOKIE['discuz_collapse'], $key) === FALSE) {   
          $collapseimg[$key] = 'collapsed_no.gif';   
          $collapse[$key] = '';   
      } else {   
          $collapseimg[$key] = 'collapsed_yes.gif';   
          $collapse[$key] = 'display: none';   
      }   
}   
$gid = !emptyempty($gid) ? intval($gid) : 0;//区显示方式   
if(!$gid) {//如果不是区显示方式,即默认的显示所有版块的首页   
      $announcements = '';//此句与下面一段是处理论坛公告   
      if($_DCACHE['announcements']) {   
          $readapmids = !emptyempty($_DCOOKIE['readapmid']) ? explode('D', $_DCOOKIE['readapmid']) : array();   
          foreach($_DCACHE['announcements'] as $announcement) {   
              if(emptyempty($announcement['groups']) || in_array($groupid, $announcement['groups'])) {   
                  if(emptyempty($announcement['type'])) {   
                     $announcements .= '<li><a href="announcement.php?id='.$announcement['id'].'" mce_href="announcement.php?id='.$announcement['id'].'">'.$announcement['subject'].   
                        '<i>('.gmdate($dateformat, $announcement['starttime'] + $timeoffset * 3600).')</i></a></li>';   
                  } elseif($announcement['type'] == 1) {   
                     $announcements .= '<li><a href="'.$announcement['message'].'" mce_href="'.$announcement['message'].'" target="_blank">'.$announcement['subject'].   
                         '<i>('.gmdate($dateformat, $announcement['starttime'] + $timeoffset * 3600).')</i></a></li>';   
                  }   
              }   
          }   
      }   
      unset($_DCACHE['announcements']);//得到公告的字符串后,及时清空这个公告数组   
      //选出论坛列表的sql,注意这里判断了是否有访问限制,如果$accessmasks不为空,则根据某用户的特殊访问规则选出了 a.allowview这个字段等   
      $sql = !emptyempty($accessmasks) ?   
                 "SELECT f.fid, f.fup, f.type, f.name, f.threads, f.posts, f.todayposts, f.lastpost, f.inheritedmod, f.forumcolumns, f.simple, ff.description, ff.moderators, ff.icon, ff.viewperm, ff.redirect, a.allowview FROM {$tablepre}forums f   
                      LEFT JOIN {$tablepre}forumfields ff ON ff.fid=f.fid   
                      LEFT JOIN {$tablepre}access a ON a.uid='$discuz_uid' AND a.fid=f.fid   
                      WHERE f.status>0 ORDER BY f.type, f.displayorder"   
                 : "SELECT f.fid, f.fup, f.type, f.name, f.threads, f.posts, f.todayposts, f.lastpost, f.inheritedmod, f.forumcolumns, f.simple, ff.description, ff.moderators, ff.icon, ff.viewperm, ff.redirect FROM {$tablepre}forums f   
                      LEFT JOIN {$tablepre}forumfields ff USING(fid)   
                      WHERE f.status>0 ORDER BY f.type, f.displayorder";   
      $query = $db->query($sql);   
      while($forum = $db->fetch_array($query)) {//从这里开始得到两个重要数组$catlist $forumlist,保存区信息与版块列表信息   
          $forumname[$forum['fid']] = strip_tags($forum['name']);//去掉html与php标记,并存入$forumname数组,以fid为键   
          if($forum['type'] != 'group') {//如果是普通版块(如type=forum或forum=sub)而不是分区   
              $threads += $forum['threads'];//主题总数   
              $posts += $forum['posts'];//帖子总数(主题与回复)   
              $todayposts += $forum['todayposts'];//今日帖子   
              if($forum['type'] == 'forum') {//非最终子版(即type不等于sub和group)的版块   
                  if(forum($forum)) {//forum函数来自include/forum.func.php,处理版块,得到比如版主啊图标啊什么的   
                      $catlist[$forum['fup']]['forums'][] = $forum['fid'];//分区数组$catlist更新   
                      $forum['orderid'] = $catlist[$forum['fup']]['forumscount']++;//得到版块的排序,所在分区的版块总数加1,每得到一个子版,就自增1   
                      $forum['subforums'] = '';//将子版字符串设置为空的,这里不是很明白,forum函数里得到了一个相同名的字符串,这里为何要清空?   
                      $forumlist[$forum['fid']] = $forum;//将$forum数组赋值给$forumlist的一个元素   
                  }   
              } elseif(isset($forumlist[$forum['fup']])) {//如果此版块的父版块id在$forumlist中存在(由上面的if中得到),则   
                  $forumlist[$forum['fup']]['threads'] += $forum['threads'];   
                  $forumlist[$forum['fup']]['posts'] += $forum['posts'];   
                  $forumlist[$forum['fup']]['todayposts'] += $forum['todayposts'];//累加三个值   
                 if($subforumsindex && $forumlist[$forum['fup']]['permission'] == 2 && !($forumlist[$forum['fup']]['simple'] & 16) || ($forumlist[$forum['fup']]['simple'] & 8)) {   
                     $forumlist[$forum['fup']]['subforums'] .= '<a href="forumdisplay.php?fid='.$forum['fid'].'" mce_href="forumdisplay.php?fid='.$forum['fid'].'">'.$forum['name'].'</a> ';   
                  }//对版块的子版字符串进行处理   
              }   
          } else {//否则,如果是分区   
             if(!isset($_COOKIE['discuz_collapse']) || strpos($_COOKIE['discuz_collapse'], 'category_'.$forum['fid']) === FALSE) {   
                  $forum['collapseimg'] = 'collapsed_no.gif';   
                  $collapse['category_'.$forum['fid']] = '';   
              } else {   
                  $forum['collapseimg'] = 'collapsed_yes.gif';   
                  $collapse['category_'.$forum['fid']] = 'display: none';   
              }//上面是对分区开启关闭按钮的处理?   
              if($forum['moderators']) {   
                  $forum['moderators'] = moddisplay($forum['moderators'], 'flat');   
              }//区版主   
              $forum['forumscount']    = 0;   
              $catlist[$forum['fid']] = $forum;//更新区版块数组   
          }   
      }   
      foreach($catlist as  $catid => $category) {//对分区的显示进行处理,如表格宽度,是否横排版块等等   
          if($catlist[$catid]['forumscount'] && $category['forumcolumns']) {   
              $catlist[$catid]['forumcolwidth'] = floor(100 / $category['forumcolumns']).'%';   
              $catlist[$catid]['endrows'] = '';   
              if($colspan = $category['forumscount'] % $category['forumcolumns']) {   
                  while(($category['forumcolumns'] - $colspan) > 0) {   
                      $catlist[$catid]['endrows'] .= '<td> </td>';   
                      $colspan ++;   
                  }   
                  $catlist[$catid]['endrows'] .= '</tr>';   
              }   
          } elseif(emptyempty($category['forumscount'])) {   
              unset($catlist[$catid]);   
          }   
      }   
      unset($catid, $category);   
      if(isset($catlist[0]) && $catlist[0]['forumscount']) {//0表示比分区更大一级的一个&#8220;虚拟分区&#8221;(暂时这么理解,因为有时候url中有fid=0这样的出现)   
          $catlist[0]['fid'] = 0;   
          $catlist[0]['type'] = 'group';   
          $catlist[0]['name'] = $bbname;   
          $catlist[0]['collapseimg'] = 'collapsed_no.gif';   
      } else {   
          unset($catlist[0]);   
      }   
      if($whosonlinestatus == 1 || $whosonlinestatus == 3) {//显示在线情况   
          $whosonlinestatus = 1;   
          $onlineinfo = explode("\t", $onlinerecord);//$onlineinfo变量,$onlinerecord来自index.php的extract($_DCACHE)处理   
          if(emptyempty($_DCOOKIE['onlineusernum'])) {   
              $onlinenum = $db->result_first("SELECT COUNT(*) FROM {$tablepre}sessions");//在线人数   
              if($onlinenum > $onlineinfo[0]) {//如果当前数据库中取得的在线人数大于原来在线人数,则更新$onlinerecord   
                  $_DCACHE['settings']['onlinerecord'] = $onlinerecord = "$onlinenum\t$timestamp";   
                 $db->query("UPDATE {$tablepre}settings SET value='$onlinerecord' WHERE variable='onlinerecord'");//同时更新settings表   
                  require_once DISCUZ_ROOT.'./include/cache.func.php';   
                  updatesettings();//更新settings缓存   
                  $onlineinfo = array($onlinenum, $timestamp);//更新$onlineinfo数组   
              }   
              dsetcookie('onlineusernum', intval($onlinenum), 300);//将在线人数写入cookie   
          } else {   
              $onlinenum = intval($_DCOOKIE['onlineusernum']);//如果cookie中在线人数不为空,直接读出   
          }   
          $onlineinfo[1] = gmdate($dateformat, $onlineinfo[1] + ($timeoffset * 3600));//更新在线情况的时间戳   
         $detailstatus = $showoldetails == 'yes' || (((!isset($_DCOOKIE['onlineindex']) && !$whosonline_contract) || $_DCOOKIE['onlineindex']) && $onlinenum < 500 && !$showoldetails);//判断在线详情变量,这里比较复杂,仔细看一下,主要是$showoldetails == 'yes'与cookie中的首页显示啊 一些条件   
          if($detailstatus) {//以下是处理在线人数列表的   
              @include language('actions');//引用语言文件 /templates/default/actions.lang.php   
              $discuz_uid && updatesession();//更新session   
              $membercount = $invisiblecount = 0;//初始化会员数量及隐身的数量   
              $whosonline = array();//初始化数组   
              $maxonlinelist = $maxonlinelist ? $maxonlinelist : 500;//最大在线人数,如果未设置,初始化为500   
             $query = $db->query("SELECT uid, username, groupid, invisible, action, lastactivity, fid FROM {$tablepre}sessions ".(isset($_DCACHE['onlinelist'][7]) ? '' : 'WHERE uid <> 0')." ORDER BY uid DESC LIMIT ".$maxonlinelist);   
              while($online = $db->fetch_array($query)) {   
                  if($online['uid']) {//会员   
                      $membercount ++;//会员总数   
                      if($online['invisible']) {//隐身用户   
                          $invisiblecount++;   
                          continue;   
                      } else {   
                         $online['icon'] = isset($_DCACHE['onlinelist'][$online['groupid']]) ? $_DCACHE['onlinelist'][$online['groupid']] : $_DCACHE['onlinelist'][0];//用户组的图标   
                      }   
                  } else {//游客,区别是数据表session里,其uid为0   
                      $online['icon'] = $_DCACHE['onlinelist'][7];   
                      $online['username'] = $_DCACHE['onlinelist']['guest'];   
                  }   
                  $online['fid'] = $online['fid'] ? $forumname[$online['fid']] : 0;//用户正浏览版块?   
                  $online['action'] = $actioncode[$online['action']];//用户正进行的动作   
                  $online['lastactivity'] = gmdate($timeformat, $online['lastactivity'] + ($timeoffset * 3600));//用户上次访问?   
                  $whosonline[] = $online;//赋值给$whosonline数组   
              }   
              unset($actioncode, $online);//清空两个变量   
              if($onlinenum > $maxonlinelist) {//如果总在线人数大于最大在线人数(系统默认为500),分别取出已登录用户和隐身用户   
                  $membercount = $db->result_first("SELECT COUNT(*) FROM {$tablepre}sessions WHERE uid <> '0'");   
                  $invisiblecount = $db->result_first("SELECT COUNT(*) FROM {$tablepre}sessions WHERE invisible = '1'");   
              }   
              if($onlinenum < $membercount) {//如果总在线人数小于在线会员数,则更新cookie中的在线用户人数,注意是onlineusernum而不是onlinenum   
                  $onlinenum = $db->result_first("SELECT COUNT(*) FROM {$tablepre}sessions");   
                  dsetcookie('onlineusernum', intval($onlinenum), 300);   
              }   
              //总结:这里有些混乱,比如总在线人数,在线会员等等,因为变量类似,很容易看错理解错误,多看几遍吧。。。   
              $guestcount = $onlinenum - $membercount;   
              $db->free_result($query);//释放数据库连接   
              unset($online);//清空,230行不是有么?又清空一次?   
          }   
      } else {   
          $whosonlinestatus = 0;//如果后台设置不显示在线人数,则不显示在线列表   
      }   
} else {//对应第77行,如果是分区显示,如url为:index.php?gid=2,则调用下面这个文件,   
      require_once DISCUZ_ROOT.'./include/category.inc.php';   
}   
include template('discuz');//解析首页的模板文件

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-105493-1-1.html 上篇帖子: php函数call_user_func和call_user_func_array详解 下篇帖子: 如何调试Php?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表