久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Discuz! X 中 SESSION 機制講解

 昵稱7519349 2011-08-31

  在Discuz! X中一如繼往的,,SESSION 并沒有使用 PHP 自帶的 SESSION 機制,,而是系統(tǒng)的一套自帶的機制。

  在數(shù)據(jù)庫中可以看到有兩個 SESSION 表:
    一個是pre_common_adminsession,,是管理員登錄后臺的 SESSION 表,;
    另一個是 pre_common_session 表,是所有用戶在前臺瀏覽頁面時的 SESSION 表,。
  這兩個表都是內存表(內存表的讀寫速度遠高于 MYISAM 表及文本文件),。

  在 Discuz! X 中 SESSION 與 COOKIE 是分不開的,因為 SESSION 就是從客戶端讀取的 COOKIE ,,
  然后由瀏覽頁面時觸發(fā)相關的函數(shù)執(zhí)行,,再寫入數(shù)據(jù)庫 SESSION 表。

  我以登錄流程為例來講解程序具體是如何執(zhí)行的,。
  在前臺首頁,,點擊登錄后,彈出一個登錄窗口,,填寫好數(shù)據(jù)后,,提交。form表單提交的 URL 是:
數(shù)據(jù)提交到了 member.php 文件中,,在程序中可看到下面的代碼:
01 $mod = !in_array($discuz->var['mod'], $modarray) ? 'logging' : $discuz->var['mod'];   //mod的值即是接下來加載的php頁面
02 define('CURMODULE', $mod);
03 $modcachelist = array('register' => array('modreasons', 'stamptypeid', 'fields_required', 'fields_optional', 'ipctrl'));
04 $cachelist = array();
05 if(isset($modcachelist[CURMODULE])) {
06     $cachelist = $modcachelist[CURMODULE];
07 }
08 $discuz->cachelist = $cachelist;
09 $discuz->init();
10 runhooks();
11 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)) {

判斷語句是當游客瀏覽時,submitcheck 函數(shù)的返回值是假,,取反,,為真。
當用戶登錄時,,程序走的是else部分,,在里面可看到下面五句代碼:

} else {
            $_G['uid'] = $_G['member']['uid'] = 0;
            $_G['username'] = $_G['member']['username'] = $_G['member']['password'] = '';    //變量賦值
            $result = userlogin($_G['gp_username'], $_G['gp_password'], $_G['gp_questionid'], $_G['gp_answer'], $_G['setting']['autoidselect'] ? 'auto' : $_G['gp_loginfield']);  //從數(shù)據(jù)庫查詢用戶數(shù)據(jù),并返回相應的信息
   
            if($result['status'] > 0) {  //狀態(tài)值大于 0 ,,說明有此用戶,,可以登錄
                setloginstatus($result['member'], $_G['gp_cookietime'] ? 2592000 : 0);  //設置登錄狀態(tài),即是寫 COOKIE 操作,,COOKIE 中的數(shù)據(jù)即是 SESSION 中相應的數(shù)據(jù),,但此函數(shù)并不負責寫 SESSION 的操作

我們來看一下 source/function/function_login.php中的 setloginstatus 函數(shù),是普通的寫 COOKIE 操作,,不再具體講解:

function setloginstatus($member, $cookietime) {
    global $_G;
    $_G['uid'] = $member['uid'];
    $_G['username'] = $member['username'];
    $_G['adminid'] = $member['adminid'];
    $_G['groupid'] = $member['groupid'];
    $_G['formhash'] = formhash();
    $_G['session']['invisible'] = getuserprofile('invisible');
    $_G['member'] = $member;
    $_G['core']->session->isnew = 1;
   
    dsetcookie('auth', authcode("{$member['password']}\t{$member['uid']}", 'ENCODE'), $cookietime, 1, true);   //authcode加密
    dsetcookie('loginuser');
    dsetcookie('activationauth');
    dsetcookie('pmnum');
}

到這里可以說是登錄流程大部分已經走完,,但是 COOKIE 不清除時,會一直存在于客戶端,,如果超時,,程序中會在判斷棄用此 COOKIE,,并重新寫入。

下面我們來看一下 DZX 中 SESSION 操作的類,,在 source/class/calss_core.php 文件中:
程序中每次請求都會加載 SESSION ,,這是由核心類 discuz_core 中的 _init_session 方法來執(zhí)行的,此方法被置于 類的 init方法中,,說明每次加載類,,會自動將 SESSION 寫入。

function _init_session() {
 
    $this->session = new discuz_session();   //創(chuàng)建 SESSION 類
 
    if($this->init_session) {
        //從 COOKIE 中讀取數(shù)據(jù)
        $this->session->init($this->var['cookie']['sid'], $this->var['clientip'], $this->var['uid']);
        $this->var['sid'] = $this->session->sid;
        $this->var['session'] = $this->session->var;
        //判斷 SID 是否相等,,不等,,說明是多個用戶在同一主機上登錄網(wǎng)站,需要重新寫 COOKIE
        if($this->var['sid'] != $this->var['cookie']['sid']) {
            dsetcookie('sid', $this->var['sid'], 86400);
        }
 
        if($this->session->isnew) {
            if(ipbanned($this->var['clientip'])) {
                $this->session->set('groupid', 6);
            }
        }
 
        if($this->session->get('groupid') == 6) {
            $this->var['member']['groupid'] = 6;
            sysmessage('user_banned');
        }
        //UID 不為空,,且需要更新 SESSION 或是 SESSION 超時,,更改用戶狀態(tài),需要用戶重新登錄
        if($this->var['uid'] && ($this->session->isnew || ($this->session->get('lastactivity') + 600) < TIMESTAMP)) {
 
            $this->session->set('lastactivity', TIMESTAMP);
 
            $update = array('lastip' => $this->var['clientip'], 'lastactivity' => TIMESTAMP);
            if($this->session->isnew) {
                $update['lastvisit'] = TIMESTAMP;
            }
            DB::update('common_member_status', $update, "uid='".$this->var['uid']."'");
        }
 
    }
}

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

//此函數(shù)負責產生新的 SESSION,,但并不負責寫入數(shù)據(jù)庫
    function create($ip, $uid) {
//創(chuàng)建SESSION,執(zhí)行插入數(shù)據(jù),,由隨機函數(shù)產生一個六位隨機數(shù)即是session的唯一值時間為當前時間,,sid為cookie中的sid
        $this->isnew = true;
        $this->var = $this->newguest;
        $this->set('sid', random(6));
        $this->set('uid', $uid);
        $this->set('ip', $ip);
        $this->set('lastactivity', time());
        $this->sid = $this->var['sid'];
   
        return $this->var;
    }
//此函數(shù)負責更新 SESSION
    function update() {
        if($this->sid !== null) {
   
            $data = daddslashes($this->var);
   
            if($this->isnew) {
                $this->delete();
                DB::insert('common_session', $data, false, false, true);
            } else {
                DB::update('common_session', $data, "sid='$data[sid]'");
            }
            dsetcookie('sid', $this->sid, 86400);
        }
    }

至此我們知道了 SESSION 插入數(shù)據(jù)庫的具體函數(shù),與 COOKIE 的聯(lián)系,,但還不清楚是如何觸發(fā)此操作的,。
打開 source/function/function_core.php 文件,找到函數(shù),,updatesession ,此函數(shù)負責更新 SESSION :

function updatesession($force = false) {
   
    global $_G;
    static $updated = false;
    if(!$updated) {
        $discuz = & discuz_core::instance();
        foreach($discuz->session->var as $k => $v) {
            if(isset($_G['member'][$k]) && $k != 'lastactivity') {
                $discuz->session->set($k, $_G['member'][$k]);
            }
        }
   
        foreach($_G['action'] as $k => $v) {
            $discuz->session->set($k, $v);
        }
   
        $discuz->session->update();
   
        $updated = true;
    }
    return $updated;
}

我們在程序源碼中搜索此函數(shù),,可以看到在很多的模板中都有下面一句代碼:

{eval updatesession();}

瀏覽頁面時將觸發(fā)此函數(shù),,并將 SESSION 寫入數(shù)據(jù)庫。

整理一下思緒:
第一步:用戶登錄,,程序將 COOKIE 寫入客戶端,,這些 COOKIE 即是 SESSION 的部分數(shù)據(jù),如SID,、IP,、TIME,不包含用戶名,、密碼等關鍵信息,。
第二步,登錄成功后,,程序會自動刷新頁面,,向服務器再次發(fā)送請求,,服務器加載 discuz_core 核心類,并從 COOKIE 中讀取到 SESSION 的相關信息,,但還沒有寫入數(shù)據(jù)庫,。
第三步,核心類加載完成,,程序繼續(xù)執(zhí)行,,最后加載模板,觸發(fā) updatesession 函數(shù),,SESSION 被寫入數(shù)據(jù)庫,。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報,。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多