在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 作為前端,...