吾知网

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 6435|回复: 0
打印 上一主题 下一主题

Discuz! X 中 SESSION 机制讲解(转)

[复制链接]
跳转到指定楼层
楼主
发表于 2017-6-24 08:52:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

下面这个流程图是我在网上找到的,顺着流程图,可以更深入的学习discuz的session机制



当初始化application时,对session进行初始化。代码主要实现以下功能:

1.判断session状态是否为开启,开启则继续

2.将cookie下的sid赋值给session中 sid,保持session和cookie中的sid保持相同。当session中的sid和cookie的sid不一致或者sid不存在,则重新创建sid,并更新cookie。

3.获取上次用户活动状态,如果未登录,则将用户组设置为游客并关联ip。如果登录,记录用户上次登录时间和ip。

代码如下:source/class/discuz/discuz_application.PHP

[php] view plain copy
print?


  • private function _init_session() {  
  •   
  •         $sessionclose = !empty($this->var['setting']['sessionclose']);  
  •         $this->session = $sessionclose ? new discuz_session_close() : new discuz_session();  
  •   
  •         if($this->init_session)  {  
  •             $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;  
  •   
  •             if(!empty($this->var['sid']) && $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;  
  •                 if(!defined('IN_MOBILE_API')) {  
  •                     sysmessage('user_banned');  
  •                 } else {  
  •                     mobile_core::result(array('error' => 'user_banned'));  
  •                 }  
  •             }  
  •   
  •             if($this->var['uid'] && !$sessionclose && ($this->session->isnew || ($this->session->get('lastactivity') + 600) < TIMESTAMP)) {  
  •                 $this->session->set('lastactivity', TIMESTAMP);  
  •                 if($this->session->isnew) {  
  •                     if($this->var['member']['lastip'] && $this->var['member']['lastvisit']) {  
  •                         dsetcookie('lip', $this->var['member']['lastip'].','.$this->var['member']['lastvisit']);  
  •                     }  
  •                     C::t('common_member_status')->update($this->var['uid'], array('lastip' => $this->var['clientip'], 'port' => $this->var['remoteport'], 'lastvisit' => TIMESTAMP));  
  •                 }  
  •             }  
  •   
  •         }  
  •     }  

创建sid代码:source/class/discuz/discuz_session;

[php] view plain copy
print?


  • public function create($ip, $uid) {  
  •         $this->isnew = true;  
  •         $this->var = $this->newguest;  
  •         $this->set('sid', random(6));  
  •         $this->set('uid', $uid);  
  •         $this->set('ip', $ip);  
  •         $uid && $this->set('invisible', getuserprofile('invisible'));  
  •         $this->set('lastactivity', time());  
  •         $this->sid = $this->var['sid'];  
  •         return $this->var;  
  •     }  


在论坛开发或者模版制作中,比较关心的session是用户在线时长和用户登录状态记录。

关于在线时长的知识,请参考:为什么Discuz! X会员在线时间不更新,解析dz在线时间机制


看了discuz的session机制,有一点拙见:

为什么我们要用数据库来记录session状态呢?

我觉得一来是数据库可以实现持久化的效果。二来,对于一个大中型的网站,例如社交网站,或电商网站,需要一个稳定的状态共享的确保。就像一个人的旅行,他将所有的现金集中放到银行,每到达一个目的地的时候,如果需要就可以很方便的仅仅使用银行卡就可以解决金钱问题,也可以在旅途中将额外的金钱随时存入银行。这样的目的,使得他能在不同时刻不同地点来进行金钱的存取,即使说有一天他身上取出的现金丢了,也可以使用银行卡来保证剩下的旅途的金钱保障。大的网站会将session独立出来,放置在专用的服务器上,当分布系统有宕机出现,备用的容错系统就可以很快的恢复到之前的状态。当然这一个过程需要很多方面的支持才行,这里只是一个很小的session部分。

而就discuz的session中,session记录表中只记录一些初始的状态,更多的都是使用cookie来记录。这和discuz的服务对象是分不开的,假如当有一天,discuz成了shopnc,session能实现的就远远不止记录当前状态这么少了。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|吾知网 ( 粤ICP备13013563号-1 )

GMT+8, 2024-12-22 20:41 , Processed in 1.125000 second(s), 8 queries , Memcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表