新建的论坛没有多少用户,不怎么活跃;于是有一些站长就想通过修改在线人数的方法来提高一下人气,网上有一些虚拟在线人数的插件,可以自己设置虚拟人数范
围,但是当你设置很大时,发现最高记录数据高的离谱,跟自己网站不匹配。

想对数据清零,这时却发现没这个功能,于是你去网上搜资料,只能找到一些老版本的 sql 修改方法,你运行了这些 sql 语句对新版本不起作用,最高记录依旧;却始终没发现一个适合自己 X 系列版本的清零方法。

2.jpg

带着这些疑问,我了解了下 X 系列版本的最高记录写入和调用方法:
1 、首先从界面入手,审查元素找到对应的 DIV 的 ID 和 CLASS,

3.jpg

2 、通过 DIV 找到模板文件是" template/default/forum/discuz.htm"相关代码 196-212 行是:

  1. <!--{if $detailstatus}-->
  2. <span ><a
    href="forum.php?showoldetails=no#online" title="{lang
    spread}"><img src="{IMGDIR}/collapsed_no.gif" alt="{lang spread}"
    /></a></span>
  3. <h3>
  4. <strong><a
    href="home.php?mod=space&do=friend&view=online&type=member">{lang
    onlinemember}</a></strong>
  5. <span >- <strong>$onlinenum</strong> {lang onlines}
  6. - <strong>$membercount</strong> {lang
    index_members}(<strong>$invisiblecount</strong> {lang
    index_invisibles}),
  7. <strong>$guestcount</strong> {lang index_guests}
  8. - {lang index_mostonlines}
    <strong>$onlineinfo[0]</strong> {lang on}
    <strong>$onlineinfo[1]</strong>.</span>
  9. </h3>
  10. <!--{else}-->
  11. <span ><a
    href="forum.php?showoldetails=yes#online" title="{lang
    spread}"><img src="{IMGDIR}/collapsed_yes.gif" alt="{lang spread}"
    /></a></span>
  12. <h3>
  13. <strong><a
    href="home.php?mod=space&do=friend&view=online&type=member">{lang
    onlinemember}</a></strong>
  14. <span >- {lang total} <strong>$onlinenum</strong> {lang onlines}
  15. - {lang index_mostonlines}
    <strong>$onlineinfo[0]</strong> {lang on}
    <strong>$onlineinfo[1]</strong>.</span>
  16. </h3>
  17. <!--{/if}-->

3 、分析模板文件代码,可知变量 $onlineinfo[0] 是最高记录,$onlineinfo[1] 是最高记录的时间,根据变量全局搜到
source/module/forum/forum_index.php 这个文件,发现 $onlineinfo 就是在这里定义的,摘出 157-170 行并分析如下:

  1. $onlineinfo = explode(" ", $_G['cache']['onlinerecord']);
  2. //读取缓存中的最高记录和时间并写在数组 $onlineinfo 中
  3. if(empty($_G['cookie']['onlineusernum'])) {
  4. //判断在线用户数量的 cookie 是否为空,如果为空就运行下面的程序
  5. $onlinenum = DB::result_first("SELECT count(*) FROM ".DB::table('common_session'));
  6. //搜出 session 表此时的在线记录数量
  7. if($onlinenum > $onlineinfo[0]) {
  8. //如果此时在线记录数量高于 最高纪录
  9. $onlinerecord = "$onlinenum ".TIMESTAMP;
  10. //定义字符串 $onlinerecord 为最高纪录加此时的时间
  11. DB::query("UPDATE ".DB::table('common_setting')." SET svalue='$onlinerecord' WHERE skey='onlinerecord'");
  12. //更新数据库表最高纪录的 svalue 值
  13. save_syscache('onlinerecord', $onlinerecord);
  14. //保存缓存数据到'onlinerecord'中
  15. $onlineinfo = array($onlinenum, TIMESTAMP);
  16. //重新定义数组 $onlineinfo
  17. }
  18. dsetcookie('onlineusernum', intval($onlinenum), 300);
  19. //重新设置 cookie 的'onlineusernum'值
  20. } else {
  21. $onlinenum = intval($_G['cookie']['onlineusernum']);
  22. //如果在线用户数量的 cookie 存在,就读取 cookie 值
  23. }
  24. $onlineinfo[1] = dgmdate($onlineinfo[1], 'd');
  25. //格式化最高纪录时的时间格式是 「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 ".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 就好了。
效果图:

4.jpg

5.jpg