常有碰到有同學問線上人數的問題,官方預設的是顯示最大線上500人 (建議不要改動太大的值,影響頁面載入的效率) 。這裡我就和大家一起看看,線上人數是如何設定和現實的。
首先我們找到論壇首頁網站模板的處理程序頁面,source/module/forum/forum_index.php 找到如下程式碼:

  1. $onlineinfo = explode(" ", $_G['cache']['onlinerecord']);
  2. if(empty($_G['cookie']['onlineusernum'])) {
  3.                         $onlinenum = DB::result_first("SELECT count(*) FROM ".DB::table('common_session'));
  4.                         if($onlinenum > $onlineinfo[0]) {
  5.                                 $onlinerecord = "$onlinenum ".TIMESTAMP;
  6.                                 DB::query("UPDATE
    ".DB::table('common_setting')." SET svalue='$onlinerecord' WHERE
    skey='onlinerecord'");
  7.                                 save_syscache('onlinerecord', $onlinerecord);
  8.                                 $onlineinfo = array($onlinenum, TIMESTAMP);
  9.                         }
  10.                         dsetcookie('onlineusernum', intval($onlinenum), 300);
  11.                 } else {
  12.                         $onlinenum = intval($_G['cookie']['onlineusernum']);
  13.                 }

這裡$onlineinfo 為線上資訊的快取記錄,如果此值為空,則查詢 common_session 表,讀取線上人數的快取。如果當前人數大於快取最高線上人數,則更新 common_setting 表的最高線上記錄人數,並快取。如果有線上人數記錄則直接讀取線上人數。

如果後臺開啟了現實線上人數,則處理線上現會員資訊。

  1. $_G['setting']['maxonlinelist'] = $_G['setting']['maxonlinelist'] ? $_G['setting']['maxonlinelist'] : 500;

在此程式對預設顯示的線上人數預設限定為500

  1. $query = DB::query("SELECT uid, username, groupid, invisible, lastactivity, fid FROM ".DB::table('common_session')." WHERE uid>'0' LIMIT ".$_G['setting']['maxonlinelist']);
  2.                         while($online = DB::fetch($query)) {
  3.                                 $membercount ++;
  4.                                 if($online['invisible']) {
  5.                                         $invisiblecount++;
  6.                                         continue;
  7.                                 } else {
  8.                                         $online['icon']
    = !empty($_G['cache']['onlinelist'][$online['groupid']]) ?
    $_G['cache']['onlinelist'][$online['groupid']] :
    $_G['cache']['onlinelist'][0];
  9.                                 }
  10.                                 $online['lastactivity'] = dgmdate($online['lastactivity'], 't');
  11.                                 $whosonline[] = $online;
  12.                         }

這裡透過 common_session 表的查詢,搜尋出最近線上的顯示會員,這裡排除了 invisible 的隱身會員。

  1. if(isset($_G['cache']['onlinelist'][7]) && $_G['setting']['maxonlinelist'] > $membercount) {
  2.                                 $query = DB::query("SELECT uid,
    username, groupid, invisible, lastactivity, fid FROM
    ".DB::table('common_session')." WHERE uid='0' ORDER BY uid DESC LIMIT
    ".($_G['setting']['maxonlinelist'] - $membercount));
  3.                                 while($online = DB::fetch($query)) {
  4.                                         $online['icon'] = $_G['cache']['onlinelist'][7];
  5.                                         $online['username'] = $_G['cache']['onlinelist']['guest'];
  6.                                         $online['lastactivity'] = dgmdate($online['lastactivity'], 't');
  7.                                         $whosonline[] = $online;
  8.                                 }
  9.                         }

這裡如果在最大線上人數大於當前線上會員,這剩餘的部分透過遊客補全。

  1. if($onlinenum > $_G['setting']['maxonlinelist']) {
  2.                                 $membercount = $discuz->session->onlinecount(1);
  3.                                 $invisiblecount =
    DB::result_first("SELECT COUNT(*) FROM ".DB::table('common_session')."
    WHERE invisible = '1'");
  4.                         }
  5.                         if($onlinenum < $membercount) {
  6.                                 $onlinenum = $discuz->session->onlinecount(0);
  7.                                 dsetcookie('onlineusernum', intval($onlinenum), 300);
  8.                         }
  9.                         $guestcount = $onlinenum - $membercount;

以上程式碼的意思是,如果線上人數> 最大顯示線上人數,則重新統計線上會員人數。

一旦線上人數< 線上會員數,則重新統計所有線上會員數 (包括隱身) 並寫入快取。

最後由線上總人數和線上會員數得出線上遊客。