- <?php
- /*
- * April 19,2012
- * discuz二次开发学习
- * author:xuqin
- * 不能为了完成任务去做一件事,要举一反三,融会贯
- *
- * @$conn=mysql_connect("localhost","root","123456") or die ("连接数据库服务器失败");
- mysql_select_db("test",$conn);
- mysql_query("set names 'gbk'");
- $sql00="select * from `admin` where `name`='admin'";
- $query=mysql_query($sql00,$conn);
- $row=mysql_fetch_array($query);
- $username=$row['name'];
- echo $username;
- *
- * 如果用自己的方法连接数据库,只有这里(最上面)才能连接成功,不报错。
- * 如果在require_once './include/common.inc.php'; 一下用这个方法连接数据库,会报错。
- * 因为在common.inc.php中引用了db_mysql.class.php严格定义了discuz连接数据库的方法。别的方法视为非法。
- *
- * 单个数据获取载入前台页面:
- $sql="select * from {$tablepre}members where `username`='admin'";
- $query=$db->query($sql);
- $row=mysql_fetch_array($query);
- $password=$row['password'];
- 多条数据循环载入前台页面:
- $query = $db->query("SELECT * FROM {$tablepre}members");
- while( $result = $db->fetch_array($query) ){ //后台
- $oklist[] = $result;
- }
- <!--{loop $oklist $key $a}--> //前台
- $a[username]:$a[email]
- <!--{/loop}-->
- */
- define('CURSCRIPT', 'index'); //定义当前运行脚本名
- require_once './include/common.inc.php'; //引入common文件
- require_once DISCUZ_ROOT.'./include/forum.func.php'; //引入版块处理函数forum.func.php
- $discuz_action = 1;
- /*
- * “当前动作”,sessions里面保存的是一个代号,相对应的文 字在templates/default/action.lang.php文件里面
- * “当前动作”是一个全局变量$discuz_action ,在不同页面有不同的值,如在:
- * index.php $discuz_action = 1;(浏览论坛首页)
- * logging.php $discuz_action = 6;(登录论坛)
- * viewthread.php $discuz_action = 3;(浏览帖子)等等很多
- *
- * 但是用处是什么呢????
- * 个人感觉只是起到"跟踪用户"的作用,比如Discuz不是有这个功能:当前板块正在浏览的用户有哪些啊,还有点击进入首页下方”在线用户“也页面会看到一个列表,并详细记录了当前用户的”当前动作“;
- * 甚至在表cdb_sessions里面专门有个字段记录用户当前的action代号
- */
- if($cacheindexlife && !$discuz_uid && $showoldetails != 'yes' && (!$_DCACHE['settings']['frameon'] || $_DCACHE['settings']['frameon'] && $_GET['frameon'] != 'yes') && emptyempty($gid)) {
- $indexcache = getcacheinfo(0); //得到首页缓存,此函数见include/forum.func.php 157行,主要是处理index.htm
- if($timestamp - $indexcache['filemtime'] > $cacheindexlife) {//判断缓存时间是否过期,如果过期,就删除index.htm,否则读取文件,并根据系统配置决定是否显示debug信息
- @unlink($indexcache['filename']); //过期就删除
- define('CACHE_FILE', $indexcache['filename']);
- $styleid = $_DCACHE['settings']['styleid'];
- } elseif($indexcache['filename']) { //没有过期就读取
- @readfile($indexcache['filename']);
- $debug && debuginfo();
- $debug ? die('<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' : '') : '').'";</script>') : die();
- }
- }
- /*
- * 分析:$cacheindexlife-首页缓存有效期,$discuz_uid存在,$showoldetails-显示在线详情,$_DCACHE['settings']['frameon']-左右分栏模式开关,$gid-版块组id,
- * 大概就是判断是否使用一个静态htm页面的条件,这个由后台是否开启首页缓存时间来决定的
- */
- $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);//上次访问时间
- /*
- * time():标准时间戳-指返回自从 Unix 纪元(格林威治时间 1970 年 1 月 1 日 00:00:00)到当前时间(指的是当前GMT标准时间)的秒数,它的值跟php系统设置的时区无关。
- * date():返回的是当前 GMT标准时间的本地化时间的“自定义格式”时间,跟php系统设置的时区有关。
- * gmdate():返回的是当前 GMT标准时间的“自定义格式”时间,跟php系统设置的时区无关。
- *
- * PHP中的时间有2个格式化函数:date()和gmdate(),在官方的文档中的描述为:
- * date -- 格式化一个本地时间/日期
- * gmdate -- 格式化一个 GMT/UTC 日期/时间,返回的是格林威治标准时(GMT)。
- * 举个例子,我们现在所在的时区是+8,那么服务器运行以下脚本返回的时间应该是这样的:
- * 当前时间假定是2007-03-14 12:15:27
- * echo date('Y-m-d H:i:s', time()); 输出为:2007-03-14 12:15:27
- * echo gmdate('Y-m-d H:i:s', time()); 输出为:2007-03-14 04:15:27
- * 但是这只是在Linux+Apache下运行PHP所得的结果,如果在Windows下运行,则2个函数返回都是:2007-03-14 04:15:27。
- * 所以,我们应该给一个兼容性的写法,统一使用gmdate,并手工设置当前时区,写法改进如下:
- * echo gmdate('Y-m-d H:i:s', time() + 3600 * 8);
- * 这样不管在Linux+Apache下还是Windows下都得到了正确的结果,当然这样写还有一个好处,当网站是面向全世界的时候,那么网站用户只要设置所在的时区,程序自动根据用
- * 户设置的时区进行时间计算,数据库中信息发布时间只存当前的time()所生成的时间,那么在中国+8时区看到的发布时间是:2007-03-14 12:15:27,那么在欧洲+2时区用户看到这
- * 个信息的发布时间是:2007-03-14 06:15:27,这样信息的时间就全部对应正确了。
- */
- $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."\" />\n") : '';
- $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).'" target="_blank">'.$topic.'</a> ';
- }
- }
- //以上两段,RSS和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; //$gid板块区大类 下面包含个板块:比如:当$gid=1时,首页下面“在线会员“板块 不见了
- /*
- * 感觉有点怪怪的,$gid定义后,好像在哪个文件中在数据库cdb_forms表中查询了下,$gid定义的区板块存不存在。
- */
- 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'].'">'.$announcement['subject'].
- '<em>('.gmdate($dateformat, $announcement['starttime'] + $timeoffset * 3600).')</em></a></li>';
- } elseif($announcement['type'] == 1) {
- $announcements .= '<li><a href="'.$announcement['message'].'" target="_blank">'.$announcement['subject'].
- '<em>('.gmdate($dateformat, $announcement['starttime'] + $timeoffset * 3600).')</em></a></li>';
- }
- }
- }
- }
- unset($_DCACHE['announcements']); //得到公告的字符串后,及时清空这个公告数组
- //下面是首页板块显示逻辑处理
- $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);
- /*
- * 选出论坛列表的sql,注意这里判断了是否有访问限制,如果$accessmasks(Access标志 ,cdb_members 用户表中有这个字段)不为空,则根据某用户的特殊访问规则选出了 a.allowview这个字段等
- */
- 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'].'">'.$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表示比分区更大一级的一个“虚拟分区”(暂时这么理解,因为有时候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]);
- }
- ?>
本文转自许琴 51CTO博客,原文链接:http://blog.51cto.com/xuqin/882318,如需转载请自行联系原作者