LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1164|回复: 7

php: 数据库保存session

[复制链接]
发表于 2005-7-21 14:33:35 | 显示全部楼层 |阅读模式
读了一篇关于数据库保存session的文章,有些不懂之处,想在这里求个明白。采用数据库技术,后客户端怎么样确定session的id呢?或者客户机与服务器靠什么连接的呢? 对session_set_save_handler这个函数和PHP的这种session机制该怎么样理解呢?

代码:


PHP代码:--------------------------------------------------------------------------------

使用数据库保存session的方法

--------------------------------------------------------------------------------

使用数据库保存session的方法
php的session默认是以文件方式保存在服务器端,并且在客户端使用cookie保存变量,这就会出现一个问题,当一个用户由于某种安全原因关闭了浏览器的cookie,程序中的session相关操作将无法执行。因此,如果能以数据库保存session数据,将不受客户端设置的限制,并且在性能和扩展性等方面有一个飞跃。程序中使用关键函数是session_set_save_handler,同时要将php.ini里的session.save_handler = files 改为 user。这里我们讨论的环境是linux(freesd)+apache+mysql+php。

数据表结构:[sessions]
CREATE TABLE sessions (   
sesskey char(32) not null,   
expiry int(11) unsigned not null,   
value text not null,   
PRIMARY KEY (sesskey)   
);

程序代码:[session_inc.php]
<?php
$SESS_DBHOST = "yourhost"; /* database server hostname */
$SESS_DBNAME = "yourdb"; /* database name */
$SESS_DBUSER = "youruser"; /* database user */
$SESS_DBPASS = "yourpassword"; /* database password */

$SESS_DBH = "";
$SESS_LIFE = get_cfg_var("session.gc_maxlifetime");

function sess_open($save_path, $session_name) {
   global $SESS_DBHOST, $SESS_DBNAME, $SESS_DBUSER, $SESS_DBPASS, $SESS_DBH;

   if (! $SESS_DBH = mysql_pconnect($SESS_DBHOST, $SESS_DBUSER, $SESS_DBPASS)) {
       echo "<li>Can't connect to $SESS_DBHOST as $SESS_DBUSER";
       echo "<li>MySQL Error: " . mysql_error();
       die;
   }

   if (! mysql_select_db($SESS_DBNAME, $SESS_DBH)) {
       echo "<li>Unable to select database $SESS_DBNAME";
       die;
   }

   return true;
}

function sess_close() {
   return true;
}

function sess_read($key) {
   global $SESS_DBH, $SESS_LIFE;

   $qry = "SELECT value FROM session_tbl WHERE sesskey = '$key' AND expiry > " . time();
   $qid = mysql_query($qry, $SESS_DBH);

   if (list($value) = mysql_fetch_row($qid)) {
       return $value;
   }

   return false;
}

function sess_write($key, $val) {
   global $SESS_DBH, $SESS_LIFE;

   $expiry = time() + $SESS_LIFE; //过期时间
   $value = addslashes($val);

   $qry = "INSERT INTO session_tbl VALUES ('$key', $expiry, '$value')";
   $qid = mysql_query($qry, $SESS_DBH);

   if (! $qid) {
       $qry = "UPDATE session_tbl SET expiry = $expiry, value = '$value' WHERE sesskey = '$key' AND expiry > " . time();
       $qid = mysql_query($qry, $SESS_DBH);
   }

   return $qid;
}

function sess_destroy($key) {
   global $SESS_DBH;

   $qry = "DELETE FROM session_tbl WHERE sesskey = '$key'";
   $qid = mysql_query($qry, $SESS_DBH);

   return $qid;
}

function sess_gc($maxlifetime) {
   global $SESS_DBH;

   $qry = "DELETE FROM session_tbl WHERE expiry < " . time();
   $qid = mysql_query($qry, $SESS_DBH);

   return mysql_affected_rows($SESS_DBH);
}

session_set_save_handler(
"sess_open",
"sess_close",
"sess_read",
"sess_write",
"sess_destroy",
"sess_gc");

session_start();
?>

完成以上步骤后,在程序中使用require("session_inc.php")来代替session_start()即可,其他的session函数还是象以前一样的方法调用
发表于 2005-7-21 14:39:50 | 显示全部楼层
也不是很难理解,php默认是把session数据保存到磁盘中,整个创建->读写->销毁->回收都是在磁盘中操作文件完成的,自定义则可以将session数据放在数据库中处理,这样在重负荷应用中session的读写就不会那么辛苦了,呵呵,还可以自定义session的读写规则
回复 支持 反对

使用道具 举报

发表于 2005-7-21 14:41:00 | 显示全部楼层
至于第一个,更简单,客户端的cookie会保存PHPSESSID
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-7-27 12:03:14 | 显示全部楼层

如果客户端禁用了COOKIE呢

Post by nbxmedia
至于第一个,更简单,客户端的cookie会保存PHPSESSID



如果客户端禁用了COOKIE,怎么确定客户端与服务器的联系呢?
回复 支持 反对

使用道具 举报

发表于 2005-7-27 14:12:30 | 显示全部楼层
........那就没用了,http是无状态协议。。。。。。。
回复 支持 反对

使用道具 举报

发表于 2005-7-30 16:35:49 | 显示全部楼层
我觉得不可以禁用cookie吧?
反正我这边测试不行。
回复 支持 反对

使用道具 举报

发表于 2005-7-31 10:30:09 | 显示全部楼层
Post by nbxmedia
........那就没用了,http是无状态协议。。。。。。。

php会自动复写(rewrite),将sessionid加在url上...
回复 支持 反对

使用道具 举报

发表于 2005-7-31 10:33:57 | 显示全部楼层
用数据库的这种方法,只是重新写了一套function而已...
这种方法可以实现session共享(多个web,domain都可以, java web 程序改成数据库也可以与之共享,现在已经有这样的开源方案).
回复 支持 反对

使用道具 举报

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

本版积分规则

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