欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

关于session id销毁的问题,请教各位

程序员文章站 2022-05-25 10:48:34
...
做一个简单的登录功能,用session_set_save_handler把session数据保存到数据库来管理
问题来了,同一个浏览器下当第一个用户登录的时候,正常,当第二个用户登录的时候我的做法是销毁先前的session,然后再创建一个session ,因为同一个浏览只允许一个 session id存在

一下是代码
function open($save_path, $session_name) {
return(true);
}
function close() {
return(true);
}
function read($id) {
$sql = "select * from session where sess_id='$id'";
if ($result = mysql_query($sql)) {

if ($row = mysql_fetch_array($result)) {
return $row["session_data"];
}
} else {
return "";
}
}
function write($id, $sess_data) {
$data_array = explode("username",$sess_data);
$i = 0;
foreach ($data_array as $data_item){

if($i == 1){
$data_array_sub = explode("\"",$data_item);
$username = $data_array_sub[1];
break;
// echo $username;
}
$i++;
}
if($username != null && strlen($username)>0){
$con = mysql_connect("127.0.0.1", "root" , "111111");
mysql_select_db("session");
$sql = "update `session` set `session_time`='".time()."',`session_data`='$sess_data' where `username`='$username' and `sess_id`='$id'";
$result = mysql_query($sql);
}
if ($result==true) {
return true;
} else {
return false;
}
}
function destroy($id) {
$sql = "update session set sess_id='',session_data='' where sess_id='$id'";
if ($result = mysql_query($sql)) {
return true;
} else {
return false;
}
}
function gc($maxlifetime) {
$sql = "update `session` set sess_id='',session_data='' where unix_timestamp(now()) -`session_time` > '1800' and LENGTH(sess_id)>1";
$result = mysql_query($sql);
if ($result == true) {
echo $sql;
return true;
} else {
echo "error";
return false;
}

}
session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
session_start();
?>
//文件名是session_user_start.php
在login.php中的代码是


require_once "config/session_user_start.php";
$_SESSION['login'] = 1;
$_SESSION['id_user'] =11;
....login.php后面的代码省略

这样做是没有问题的

问题来了,因为session id一样,当第二个用户登录的时候我想将以前登录的session数据清除,就修改login.php如下
require_once "config/session_user_start.php";
session_unset();
session_destroy();
require_once "config/session_user_start.php";
$_SESSION['login'] = 1;
$_SESSION['id_user'] =11;
....login.php后面的代码省略

当销毁的时候destroy函数有调用,但是销毁过后login.php执行完调用write($id, $sess_data)的时候
$sess_data的值就是空了,第二个的session数据就写不进去了
session_unset();
session_destroy();这两句执行完以后重新再
session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
session_start();不可以吗,为什么得不到数据呢,请教各位

补充一下
session_unset()
释放当前在内存中已经创建的所有$_SESSION变量,但不删除session文件以及不释放对应的session id

session_destroy()
删除当前用户对应的session文件以及释放session id,内存中的$_SESSION变量内容依然保留
为什么销毁了,再调用session_start();session id的值还是一样的


回复讨论(解决方案)

require_once "config/session_user_start.php";
已加载就不加载,所以无论你之后执行多少遍,都是无效的
session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
只是绑定工作函数,与具体数据无关。多次执行也没什么意义
何况 php5.4 起,重复 session_start() 是要报错的

改变 sessionid 的值用 session_regenerate_id 函数

所以流程应是
require_once "config/session_user_start.php";
if(是新用户吗) {
session_regenerate_id();
$_SESSION 赋值操作
}
正常的验证操作

由于 sessionid 已经改变,原先的 sessionid 自然就失效了
清理由 gc 完成

require_once "config/session_user_start.php";
已加载就不加载,所以无论你之后执行多少遍,都是无效的
session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
只是绑定工作函数,与具体数据无关。多次执行也没什么意义
何况 php5.4 起,重复 session_start() 是要报错的

改变 sessionid 的值用 session_regenerate_id 函数

所以流程应是
require_once "config/session_user_start.php";
if(是新用户吗) {
session_regenerate_id();
$_SESSION 赋值操作
}
正常的验证操作

由于 sessionid 已经改变,原先的 sessionid 自然就失效了
清理由 gc 完成


感谢