php - session_set_save_handler - 为什么此代码不起作用?

标签 php mysql session session-set-save-handler

我一直在尝试将 PHP session 数据保存在 MySQL 数据库中,但无法使其工作。

举个简单的例子,下面的代码应该在每次访问时增加一个计数器。我见过其他示例等,但是有人可以告诉我为什么这段代码不起作用吗? (Apache/2.2.11 (Win32) DAV/2 mod_ssl/2.2.11 OpenSSL/0.9.8i PHP/5.2.9 MySQL 客户端版本:5.0.51a)

这是mysql数据库表:

CREATE TABLE IF NOT EXISTS `sessions` (
  `session_ID` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
  `session_data` mediumblob NOT NULL,
  `access` int(10) unsigned NOT NULL,
  PRIMARY KEY (`session_ID`),
  KEY `access` (`access`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

以及 PHP 代码(只需插入您的数据库凭据):

<?PHP

function mysession_open()
{

    global $sdbc;   // Session Database Connection

    if ($sdbc) {
        return true;
    } else {
        return false;
    }

}

function mysession_close()
{

    global $sdbc;

    return mysqli_close($sdbc);

}

function mysession_read($session_id)
{
    global $sdbc;

    $session_id = mysqli_real_escape_string($sdbc, $session_id);

    $sql_sel    = "SELECT session_data FROM sessions WHERE session_id = '$session_id'";
    $data_sel   = mysqli_query($sdbc, $sql_sel);
    $row_sel     = mysqli_fetch_array($data_sel);

    if (isset($row_sel['session_data'])) {
        return $row_sel['session_data'];
    } else {
        return '';
    }

}

function mysession_write($session_id, $session_data)
{
    global $sdbc;

    $access = time();

    $session_id    = mysqli_real_escape_string($sdbc, $session_id);
    $access        = mysqli_real_escape_string($sdbc, $access);
    $session_data   = mysqli_real_escape_string($sdbc, $session_data);

    $sql_write  =   "REPLACE INTO sessions (session_ID, session_data, access) " .
                    "VALUES ('$session_id', '$session_data', '$access')";

    return mysqli_query($sdbc, $sql_write);

}

function mysession_destroy($session_id)
{
    global $sdbc;

    $session_id = mysqli_real_escape_string($sdbc, $session_id);

    return mysqli_query($sdbc, $sql_del);
}


function mysession_gc($max)
{
    global $sdbc;

    $old = time() - $max;
    $old = mysqli_real_escape_string($sdbc, $old);

    $sql_old = "DELETE FROM sessions WHERE access < '$old'";

    return mysqli_query($sdbc, $sql_old);

}

global $sdbc;
$sdbc = mysqli_connect('localhost', '...', '...', '...') or die('Could not connect to SDBC');

session_set_save_handler('mysession_open','mysession_close','mysession_read','mysession_write','mysession_destroy','mysession_gc');
session_start();

if (isset($_SESSION['counter'])) {
    echo "counter is already set and it is " . $_SESSION['counter'] . '<br />';
    $_SESSION['counter']++;
} else {
    echo "counter is not set.  setting to 1<br />";
    $_SESSION['counter'] = 1;
}

echo "<br />Dumping SESSION data:<br />";
var_dump($_SESSION);

session_write_close();

?>

预先感谢您的帮助。

如果您注释掉 session_set_save_handler 代码行,它就可以正常工作(它会递增)。但使用保存处理程序则不然。

最佳答案

您的查询调用都没有任何错误检查。不要盲目地假设数据库部分有效,而是在每个阶段进行一些基本的错误检查,例如:

function mysession_write($session_id, $session_data) {
    global $sdbc;

    [...snip...]

    $stmt = mysqli_query($sdbc, $sql_write);
    if ($stmt === FALSE) {
       error_log("Failed to write session $session_id: " . mysqli_error($sdbc);
    }
    return($stmt);
}

查询成功的方法只有一种,但失败的方法有无数种。

关于php - session_set_save_handler - 为什么此代码不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4045210/

相关文章:

php - MySQL STR_TO_DATE() 返回无效日期

php - Laravel Model函数 “create”和 “insert”有什么区别?

php - 连接两个表并得到结果

php - 谷歌地图地理编码从浏览器工作,而不是从 PHP 服务器工作

mysql - `UPDATE ... WHERE ... ` InnoDB 多行锁定

php - 如何在数据库查询结果中显示多个html表中的数据

ruby-on-rails - 检测 Rails 4 session cookie 篡改

google-chrome - Chrome 开发者工具中的 "Session Storage"是什么?

php - 使用 $_POST 插入带有 PDO 准备语句的 MySQL 数据库

asp.net-mvc - 使用表单例份验证在ASP.NET MVC上的哪里存储已记录的用户信息?