Discuz X中SESSION機制例項詳解

2022-09-26 20:24:13 字數 3226 閱讀 3520

在discuz! x中一如繼往的,session 並沒有使用 php 自帶的 session 機制,而是系統的一套自帶的機制。

在資料庫中可以看到有兩個 session 表:

乙個是pre_common_adminsession,是管理員登入後台的 session 表;

另乙個是 pre_common_session 表,是所有使用者在前台瀏覽頁面時的 session 表。

這兩個表都是記憶體表(記憶體表的讀寫速度遠高於 myisam 表及文字檔案)。

在 discuz! x 中 session 與 cookie 是分不開的,因為 session 就是從客戶端讀取的 cookie ,

然後由瀏覽頁面時觸發相關的函式執行,再寫入資料庫 session 表。

我以登入流程為例來講解程式具體是如何執行的。

在前台首頁,點選登入後,彈出乙個登入視窗,填寫好資料後,提交。form表單提交的 url 是:

複製** **如下:

程式設計客棧p:">http:

資料提交到了 member.php 檔案中,在程式中可看到下面的**:

$mod = !in_array($discuz->var['mod'], $modarray) ? 'logging' : $discuz->var['mod']; //mod的值即是接下來載入的php頁面

define('curmodule', $mod);

$modcachelist = array('register' => array('modreasons', 'stamptypeid', 'fields_required', 'fields_optional', 'ipctrl'));

$cachelist = array();

if(isset($modcachelist[curmodule]))

$discuz->cachelist = $cachelist;

$discuz->init();

runhooks();

require discuz_root.'./source/module/member/member_'.$mod.'.php'; //完成程式的包含操作

開啟source/module/member/member_logging.php檔案,是乙個類,在類的前面可看到下面三句**:

$ctl_obj = new logging_ctl();

$method = 'on_'.$_g['gp_action']; // $_g['gp_action'] 等於action的值即 login

$ctl_obj->$method(); //$ctl_obj->on_login();

在類中可找到login方法,在方法中,大約 56 行有下面乙個判斷語句:

if(!submitcheck('loginsubmit', 1, $seccodecheck)) else \t", 'encode'), $cookietime, 1, true); //authcode加密

dsetcookie('loginuser');

dsetcookie('activationauth');

dsetcookie('pmnum');

}到www.cppcns.com這裡可以說是登入流程大部分已經走完,但是 cookie 不清除時,會一直存在於客戶端,如果超時,程式中會在判斷棄用此 cookie,並重新寫入。

下面我們來看一下 dzx 中 session 操作的類,在 source/class/calss_core.php 檔案中:

程式中每次請求都會載入 session ,這是由核心類 discuz_core 中的 _init_session 方法來執行的,此方法被置於 類的 init方法中,說明每次載入類,會自動將 session 寫入。

function _init_session()

if($this->session->isnew)

} if($this->session->get('groupid') == 6)

//uid 不為空,且需要更新 session 或是 session 超時,更改使用者狀態,需要使用者重新登入

if($this->var['uid'] && ($this->session->isnew || ($this->session->get('lastactivity') + 600) < timestamp))

db::update('common_member_status', $update, "uid='".$this->var['uid']."'");

} } }

操作 session 的類是 discuz_session ,我們看這個類裡面的兩個方法:

//此函式負責產生新的 session,但並不負責寫入資料庫

function create($ip, $uid)

//此函式負責更新 session

function update() else

dsetcookie('sid', $this->sid, 86400); } }

至此我們知道了 session 插入資料庫的具體函式,與 cookie 的聯絡,但還不清楚是如何觸發此操作的。

開啟 source/function/function_core.php 檔案,找到函式,updatesession ,此函式負責更新 session :

function updatesession($force = false)

} foreach($_g['action'] as $k => $v)

$discuz->session->update();

$updated = true;

} return $updated;

}我們在程式原始碼中搜尋此函式,可以看到在很多的模板中都有下面一句**:

複製** **如下:

瀏覽頁面時將觸發此函式,並將 session 寫入資料庫。

整理一下思緒:

第一步:使用者登入,程式將 cookie 寫入客戶端,這些 cookie 即是 session 的部分資料,如sid、ip、time,不包含使用者名稱、密碼等關鍵資訊。

第二步,登入成功後,程式會自動重新整理頁面,向伺服器再次傳送請求,伺服器載入 discuz_core 核心類,並從 cookie 中讀取到 session 的相關資訊,但還沒有寫入資料庫。

第三步,核心類載入完成,程式繼續執行,最後載入模板,觸發 updatesession 函式,session 被寫入資料庫。

本文標題: discuz!x中session機制例項詳解

本文位址:

Session中StateServer的使用方法

最近專案中用到 session的stateserver模式,我們知道sessionstate有四種模式 off,inproc,stateserver,sqlserver。而stateserver 是將session儲存到記憶體中的,使用此種方式必須啟動asp.net 狀態windows服務。stat...

vue express架構中session失效問題

我們使用node作為服務端,經常會用到express session或者cookie session 來儲存資料,但是我們會經常遇到 在vue端發起post請求的時候,node 端響應介面的時候,我們的req.session會出現失效的問題,出現這個bug的原因是客戶端傳送post請求的時候發生了跨...

DiscuzX 論壇安裝公升級

discuzx 安裝 系統環境 linux 系統架構 最前端兩台nginx 使用keepalived 來實現 高可用和負載均衡 然後使用這兩台nginx 來發布後端的多個應用,後端包括 tomcat 和 php 環境 軟體環境 nginx nginx php mysql 第乙個nginx 作為前端,...