本帖最后由 otherbank 于 2015-3-17 16:28 编辑
新建的论坛没有多少用户,不怎么活跃;于是有一些站长就想通过修改在线人数的方法来提高一下人气,网上有一些虚拟在线人数的插件,可以自己设置虚拟人数范围,但是当你设置很大时,发现最高记录数据高的离谱,跟自己网站不匹配,想对数据清零,这时却发现没这个功能,于是你去网上搜资料,只能找到一些老版本的sql修改方法,你运行了这些sql语句对新版本不起作用,最高记录依旧;却始终没发现一个适合自己X系列版本的清零方法。
带着这些疑问,我了解了下X系列版本的最高记录写入和调用方法:
1、首先从界面入手,审查元素找到对应的DIV的ID 和CLASS,
2、通过DIV找到模板文件是"\template\default\forum\discuz.htm"相关代码196-212行是:
- <!--{if $detailstatus}-->
- <span class="o"><a href="forum.php?showoldetails=no#online" title="{lang spread}"><img src="{IMGDIR}/collapsed_no.gif" alt="{lang spread}" /></a></span>
- <h3>
- <strong><a href="home.php?mod=space&do=friend&view=online&type=member">{lang onlinemember}</a></strong>
- <span class="xs1">- <strong>$onlinenum</strong> {lang onlines}
- - <strong>$membercount</strong> {lang index_members}(<strong>$invisiblecount</strong> {lang index_invisibles}),
- <strong>$guestcount</strong> {lang index_guests}
- - {lang index_mostonlines} <strong>$onlineinfo[0]</strong> {lang on} <strong>$onlineinfo[1]</strong>.</span>
- </h3>
- <!--{else}-->
- <span class="o"><a href="forum.php?showoldetails=yes#online" title="{lang spread}"><img src="{IMGDIR}/collapsed_yes.gif" alt="{lang spread}" /></a></span>
- <h3>
- <strong><a href="home.php?mod=space&do=friend&view=online&type=member">{lang onlinemember}</a></strong>
- <span class="xs1">- {lang total} <strong>$onlinenum</strong> {lang onlines}
- - {lang index_mostonlines} <strong>$onlineinfo[0]</strong> {lang on} <strong>$onlineinfo[1]</strong>.</span>
- </h3>
- <!--{/if}-->
复制代码 3、分析模板文件代码,可知变量$onlineinfo[0]是最高记录,$onlineinfo[1]是最高记录的时间,根据变量全局搜到
\source\module\forum\forum_index.php这个文件,发现$onlineinfo就是在这里定义的,摘出157-170行并分析如下:
- $onlineinfo = explode("\t", $_G['cache']['onlinerecord']);
- //读取缓存中的最高记录和时间并写在数组$onlineinfo 中
- if(empty($_G['cookie']['onlineusernum'])) {
- //判断在线用户数量的cookie是否为空,如果为空就运行下面的程序
- $onlinenum = DB::result_first("SELECT count(*) FROM ".DB::table('common_session'));
- //搜出session表此时的在线记录数量
- if($onlinenum > $onlineinfo[0]) {
- //如果此时在线记录数量高于 最高纪录
- $onlinerecord = "$onlinenum\t".TIMESTAMP;
- //定义字符串$onlinerecord 为最高纪录加此时的时间
- DB::query("UPDATE ".DB::table('common_setting')." SET svalue='$onlinerecord' WHERE skey='onlinerecord'");
- //更新数据库表最高纪录的svalue值
- save_syscache('onlinerecord', $onlinerecord);
- //保存缓存数据到'onlinerecord'中
- $onlineinfo = array($onlinenum, TIMESTAMP);
- //重新定义数组$onlineinfo
- }
- dsetcookie('onlineusernum', intval($onlinenum), 300);
- //重新设置cookie的'onlineusernum'值
- } else {
- $onlinenum = intval($_G['cookie']['onlineusernum']);
- //如果在线用户数量的cookie存在,就读取cookie值
- }
- $onlineinfo[1] = dgmdate($onlineinfo[1], 'd');
- //格式化最高纪录时的时间格式是“2011-9-28”
复制代码 看到这里很多人会认为直接DB::query("UPDATE ".DB::table('common_setting')." SET svalue='$onlinerecord' WHERE skey='onlinerecord'");的sql语句不就行了吗。其实不然,重点在要修改在线最高记录是要修改缓存$_G['cache']['onlinerecord']的值,如果你不修改这个缓存值并且新的在线人数又不高于缓存中最高记录,数组$onlineinfo根本不会重新被赋值,也就没法完成清零 ,哪怕你把表的'common_setting'的值改为“0 1314XXXXXXX”,最高记录会依然读取缓存最高记录。
难点就在$_G['cache']['onlinerecord'])从何而来,变量追溯cache的值要读pre_common_syscache 这个表,缓存数据data`是 mediumblob 这个数据类型,只能在程序里面修改,不能sql语句的方法修改,所以得用插件或者单独写个程序页面来清零,也就是用到上面13行的代码save_syscache('onlinerecord', $onlinerecord);来更新缓存的数值。
4、分析到这里修改方法就有了,定义一下变量$onlinerecord ,更新一下数据库表'common_setting'再保存一下缓存就好了:
$onlinerecord = "$onlinenum\t".TIMESTAMP;
DB::query("UPDATE ".DB::table('common_setting')." SET svalue='$onlinerecord' WHERE skey='onlinerecord'");
save_syscache('onlinerecord', $onlinerecord);
重设需要两个值,一个是是最高记录值,一个是最高纪录的时间,就做了个简单的页面方便大家修改,直接把下面的附件传到Discuz! X2根目录下运行就行了:utf8编码的运行:http://www.xxxxxx.com/onlineutf8.php ;gbk的运行:http://www.xxxxxx.com/onlinegbk.php就好了。
效果图:
附件下载utf8的:
附件下载gbk的:
|