新建的論壇沒有多少使用者,不怎麼活躍;於是有一些站長就想透過修改線上人數的方法來提高一下人氣,網上有一些虛擬線上人數的外掛,可以自己設定虛擬人數範
圍,但是當你設定很大時,發現最高記錄資料高的離譜,跟自己網站不匹配。
想對資料清零,這時卻發現沒這個功能,於是你去網上搜資料,只能找到一些老版本的 sql 修改方法,你執行了這些 sql 語句對新版本不起作用,最高記錄依舊;卻始終沒發現一個適合自己 X 系列版本的清零方法。

帶著這些疑問,我瞭解了下 X 系列版本的最高記錄寫入和呼叫方法:
1 、首先從介面入手,審查元素找到對應的 DIV 的 ID 和 CLASS,

2 、透過 DIV 找到模板檔案是" template/default/forum/discuz.htm"相關程式碼 196-212 行是:
- <!--{if $detailstatus}-->
- <span ><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 >- <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 ><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 >- {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(" ", $_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 ".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 ".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 就好了。
效果圖:

