对数据库支持的自定义会话处理程序进行故障排除-值在页面加载之间不持久


Troubleshooting database-backed custom session handler - values are not persisting between page loads

我正试图让我的自定义会话正常工作,但我的变量无法在一页又一页之间持久存在。如果我删除require行并将其替换为session_start();它运行良好。所有这些文件都在同一目录中,我在php.ini文件中将session.save_handler设置为user。

第一个HTML页面

<?php 
require("sessionSetup.php");
$_SESSION['test'] = "session test";
session_regenerate_id();
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>sessions test</title>
<script type="text/javascript">
<!--
alert("Test: <?php echo $_SESSION['test'];?>");
//-->
</script>
</head>
<body>
    <a href="session2.php">Click here to go to session2.</a>
</body>
</html>

第二个HTML页面

<?php
require("sessionSetup.php");
//session_start();  
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>sessions test</title>
<script type="text/javascript">
<!--
alert("Test: <?php echo $_SESSION['test'];?>");
//-->
</script>
</head>
<body>
    <a href="session.php">Click here to go to session.</a>
</body>
</html>

sessionSetup.PHP

<?php
session_set_save_handler('_open','_close','_read','_write','_destroy','_clean');
session_start();

function _open(){
global $_sess_db;
if($_sess_db = mysql_connect(host,user,password)){
    return mysql_select_db(db, $_sess_db)or die("cannot select DB");
}
return false;   
} 
function _close(){
global $_sess_db;
return mysql_close($_sess_db);
}
function _read($id){
global $_sess_db; 
$id = mysql_real_escape_string($id); 
$sql = "SELECT data FROM session WHERE id = '$id'";
if ($result = mysql_query($sql, $_sess_db)) {
    if (mysql_num_rows($result)) {
        $record = mysql_fetch_assoc($result); 
        return $record['data'];
    }
} 
return '';
}
function _write($id, $data){
global $_sess_db; 
$access = time(); 
$id = mysql_real_escape_string($id);
$access = mysql_real_escape_string($access);
$data = mysql_real_escape_string($data); 
$sql = "REPLACE INTO session VALUES ('$id', '$access', '$data')"; 
return mysql_query($sql, $_sess_db);
}
function _destroy($id){
global $_sess_db; 
$id = mysql_real_escape_string($id); 
$sql = "DELETE FROM session WHERE id = '$id'"; 
return mysql_query($sql, $_sess_db);
}
function _clean($max){
global $_sess_db; 
$old = time() - $max;
$old = mysql_real_escape_string($old); 
$sql = "DELETE FROM session WHERE access < '$old'"; 
return mysql_query($sql, $_sess_db);
}
?>

我在这里用伪信息替换了数据库登录的内容。此外,当我检查phpadmin时,我的会话数据库中没有任何信息。我在第二个HTML页面上得到的只是一个空值。我已经为此工作了一段时间,但没有取得任何进展。我能得到的任何帮助都将不胜感激。

代码看起来不错。

确保用于存储会话数据的数据库表设置正确,因为会话处理程序函数似乎没有任何错误检查。

会话不工作的最可能原因是会话表的id或数据列不够大,无法容纳全部信息。访问权限应为int,请尝试id和数据的不同大小的varchar。

正如session_start()上php手册页面中强调的那样,在任何内容输出到浏览器之前,必须执行。最有可能的是,您所需的文件(sessionSetup.php)在开头或结尾有几个空位,这些空位没有被解释为php,因此被输出到bowser。要解决此问题,只需将session_start放在require("sessionSetup.php");之前(也不要忘记在执行此操作后从会话设置文件中删除session_start)。或者你可以创建一个输出缓冲区。