DZ的session很怪,基本脱离了session的原始定义
在dz中,每一次更新刷新页面都是重新查一次数据库,更确切的说应该是利用cookie在保持状态
数据库里有一个session表,但是整个看起来只是统计在线人数和更新在线时间等小作用。
所以我在想,如果用户浏览器不能使用cookie比如手机,是不是就登陆不成功呢?
答案似乎是这样的,因为core里首先是_init_user(),然后才是_init_session(),会根据初始化用户得到的值来载入session信息。
如果利用地址栏传递sid来保持状态的话,因为表里有IP段信息,我觉得是安全的。
可惜他的整个流程里sid值是从cookie里获取的,断了这条路。。。
如果要实现地址传递sid值,应该还需要改不少东西。
在对整个用户进行初始化的过程中,有几个相关的过程也是在这儿完成的,比如统计在线时间,上次登录时间和最后活动时间。
流程如下:
首先提取用户cookie信息中的auth值,变成uid和密码,比对DB中的信息,成功则用户判断成功
载入用户信息,放入member数组。给cookie中的lastvisit赋值,记录本次登录时间戳。
然后进入session初始化。如果是登陆用户,根据IP,UID,SID从session表中提取信息。
如果上面三项中没有完全匹配的,则重新生成sid值并给整个session数组赋值。同时修改cookie中的sid值
在重新登陆和IP变动的情况下,对用户表的统计信息lastvisit和ip进行更新
如果是离上次活动时间大于10分钟,对session中的lastactivity进行更新
然后在模板页面的最后部分载入updatesession函数(因为session数组里还有一些action等信息需要在后续过程中获取)
在这里首先根据上次更新的时间戳判断是否超过10分钟了,而来增加用户的在线时间等信息。
然后把这个页面中补充完的session数组的信息更新到数据库里。
最后在根据DB中的lastactivity信息是否超过6小时来更新用户统计表中的lastactivity等信息。这个地方我还得看一下,因为似乎没发现更合理的更新DB中lastactivity的方法。
核心代码如下:
function _init_session() {
$this->session = new session();
if($this->init_session) {
$this->session->init($this->var['cookie']['sid'], $this->var['ip'], $this->var['uid']);
$this->var['sid'] = $this->session->sid;
$this->var['session'] = $this->session->var;
//当IP地址有更换的时候,则会自动生成新的sid值。一般在掉线或者更换主机后出现。
if($this->var['sid'] != $this->var['cookie']['sid']) {
dsetcookie('sid', $this->var['sid'], 86400);
}
//如果重新建立sid后,则会对用户进行组别判断
if($this->session->isnew) {
if(ipbanned($this->var['ip'])) {
$this->session->set('groupid', 9);//9设置为IP禁止访问组别
}
}
if($this->session->get('groupid') == 9) {
$this->var['member']['groupid'] = 9;
sysmessage('user_banned');
}
//在页面刚载入初始化session部分的时候,给lastactivity赋值
//如果用户一直保持着session状态,则这里判断上次活动时间10分钟是否已过,如果已过则重新给lastactivity赋值
if($this->var['uid'] && ($this->session->isnew || ($this->session->get('lastactivity') + 600) < TIMESTAMP)) {
$this->session->set('lastactivity', TIMESTAMP);
//如果是更换了IP的情况或者重新登陆,则在这里重新生成统计信息,每次重新登陆都会重新统计
//和updatesession里更新这信息的区别,这里主要是针对重新生成sessionDB信息后,判断为重新登陆
//对lastvisit登陆时间赋值,而那里则是针对长时间无操作,重新生成统计信息
if($this->session->isnew) {
$citya = ip2area($_G['ip']);
$city = $citya[0];
$code = $citya[1];
DB::update('users_count', array('lastip' => $this->var['ip'], 'lastvisit' => TIMESTAMP), "uid='".$this->var['uid']."'");
DB::update('users_pro', array('city' => $city, 'code' => $code),"uid='".$this->var['uid']."'");
}
}
}
}
function updatesession($force = false) {
global $_G;
static $updated = false;
if(!$updated) {
$lab = & core::instance();
$oltimespan = $_G['setting']['oltimespan'];
$lastolupdate = $lab->session->var['lastolupdate'];
//这段代码用来更新在线累计时间,大约是每10分钟添加一次
if($_G['uid'] && $oltimespan && TIMESTAMP - ($lastolupdate ? $lastolupdate : $_G['member']['lastactivity']) > $oltimespan * 60) {
DB::query("UPDATE ".DB::table('users_count')."
SET oltime=oltime+'$oltimespan'
WHERE uid='{$_G['uid']}'");
$lab->session->set('lastolupdate', TIMESTAMP);
}
//这里用来增加session里的用户隐身与否,或者其他需要储存的信息
foreach($lab->session->var as $k => $v) {
if(isset($_G['member'][$k]) && $k != 'lastactivity') {
$lab->session->set($k, $_G['member'][$k]);
}
}
foreach($_G['action'] as $k => $v) {
$lab->session->set($k, $v);
}
//把上面添加的所有session的信息进行更新到数据库
$lab->session->update();
$updated = true;
//这里对DB中的count的lastvisit和lastactivity进行更新,这里一般考虑的是没有经过注册或者登陆而直接通过cookie登陆的人
//在这里进行着更新
if($_G['uid'] && TIMESTAMP - $_G['member']['lastactivity'] > 21600) {//6小时
$citya = ip2area($_G['ip']);
$city = $citya[0];
$code = $citya[1];
DB::update('users_count', array('lastip' => $_G['ip'], 'lastactivity' => TIMESTAMP, 'lastvisit' => TIMESTAMP), "uid='$_G[uid]'", 1);
DB::update('users_pro', array('city' => $city, 'code' => $code), "uid='$_G[uid]'", 1);
}
}
return $updated;
}