新建的論壇沒有多少用户,不怎麼活躍;於是有一些站長就想通過修改在線人數的方法來提高一下人氣,網上有一些虛擬在線人數的插件,可以自己設置虛擬人數範
圍,但是當你設置很大時,發現最高記錄數據高的離譜,跟自己網站不匹配。

想對數據清零,這時卻發現沒這個功能,於是你去網上搜資料,只能找到一些老版本的 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