Jun 16
作者: 肖建彬 | 可以转载, 转载时务必以超链接形式标明文章原始出处和作者信息及版权声明
网址:http://www.xiaojb.com/archives/it/phpmysqlsession.shtml
网址: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;
程序如下:
下载: session.php
- <?php
- 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.

June 22nd, 2006 at 10:04
前一段时间我看了resin里面的session的jdbcStore实现和sessionManager,和你上面这段代码原理相似,相比多加了些cache session的代码。原本是想实现单点登录的,后来发现不更改resin源代码竟然没有简单的办法实现这个功能。超级郁闷
April 3rd, 2008 at 19:03
博主可能是考虑如果一个目录下session文件过多,造成读写session的缓慢,如果单从这个角度考虑,可以按照一定规则分目录存放,php.ini中有相关配置,建议参考
April 3rd, 2008 at 19:04
至于分布式系统,nfs和其他文件同步工具也能很好解决这些问题,不过mysql这种方式可以解决垮域验证问题
April 3rd, 2008 at 19:18
解决不了垮域问题,因为垮域是cookie要垮域(传递SID的方法除外)。