迅雷不及掩耳盗铃之势申请了Picasa Web Albums 海陀一日归来
Jun 16
作者: 肖建彬 | 可以转载, 转载时务必以超链接形式标明文章原始出处和作者信息及版权声明
网址:http://www.xiaojb.com/archives/it/phpmysqlsession.shtml

使用MySQL保存session会话较files有很多优点:
1) 有利于分布式系统,files只能保存在一台机器上
2) 有利于大访问量的系统,使用files时每个session保存在一个文件中,目录会超级大,查找session文件会比较困难,当然,也可以自己写一个有hash目录的替代。

使用MySQL保存会话首先要创建session表:

CREATE TABLE `sessions` (
`sid` char(40) NOT NULL,
`data` text NOT NULL,
`update` int(10) unsigned NOT NULL default ‘0′,
UNIQUE KEY `sid` (`sid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


程序如下:

function sess_open($path, $name) {
return TRUE;
}

function sess_close() {
return TRUE;
}

function sess_read($sid) {
global $db;
$query = $db->query(”SELECT data FROM sessions WHERE sid=’$sid’ LIMIT 1″,’SILENT’);
if($db->num_rows($query)) {
return $db->result($query, 0);
} else {
$db->query(”INSERT INTO sessions SET sid=’$sid’,update=UNIX_TIMESTAMP()”,’SILENT’);
}
return TRUE;
}

function sess_write($sid, $data) {
global $db;
$data = addslashes($data);
$db->query(”UPDATE sessions SET data=’$data’,lastupdate=UNIX_TIMESTAMP() WHERE sid=’$sid’ LIMIT 1″,’SILENT’);
return TRUE;
}

function sess_destroy($sid) {
global $db;
$db->query(”DELETE FROM sessions WHERE sid=’$sid’”,’SILENT’);
return TRUE;
}

function sess_gc($maxlifetime) {
global $db;

$query = $db->query(”DELETE FROM sessions WHERE UNIX_TIMESTAMP()-update>’$maxlifetime’”,’SILENT’);
if($db->affected_rows($query)) {
return TRUE;
}
return FALSE;
}

session_module_name();
session_set_save_handler(’sess_open’, ’sess_close’, ’sess_read’, ’sess_write’, ’sess_destroy’, ’sess_gc’);
session_start();
?>


在这个程序中,使用了Discuz!的db_mysql类,包含此程序前要打开数据库,主程序退出前不能关闭数据库,否则会出错。

还有一种保存会话的方法,效率较这种方法更高,那就是使用HEAP表,因为HEAP是将数据保存在内存里,节约内存就成了数据库设计的关键,如上面程序那样使用Text保存数据就不现实了,而且HEAP也不支持TEXT类型,Discuz!的session会话机制值得学习,它是按照自己所需要的字段,定制了表的内容,并且不依赖PHP自身的session.

5 Responses to “PHP:使用MySQL保存SESSION会话”

  1. bittercookie Says:

    前一段时间我看了resin里面的session的jdbcStore实现和sessionManager,和你上面这段代码原理相似,相比多加了些cache session的代码。原本是想实现单点登录的,后来发现不更改resin源代码竟然没有简单的办法实现这个功能。超级郁闷

  2. 孙小二 Says:

    博主可能是考虑如果一个目录下session文件过多,造成读写session的缓慢,如果单从这个角度考虑,可以按照一定规则分目录存放,php.ini中有相关配置,建议参考

  3. 孙小二 Says:

    至于分布式系统,nfs和其他文件同步工具也能很好解决这些问题,不过mysql这种方式可以解决垮域验证问题

  4. xjb Says:

    解决不了垮域问题,因为垮域是cookie要垮域(传递SID的方法除外)。

  5. mmmmmm Says:

    这里的$sid是不是就是SID?

Leave a Reply