php - 数据库 session 处理程序问题

标签 php mysql session handler

你好,我想了解 session 是如何工作的以及 session_set_handler() 是如何工作的,所以我已经开始构建一个用于 session 处理的类,但是我遇到了一些 的问题>write() 函数你能帮我解决这个问题吗?

<?php
class Session extends Model
{
    public
        $connectionName = 'sessions',
        $sessionsId,
        $sessionsData;

    public function __construct()
    {
        parent::__construct();
        session_set_save_handler(
            array($this, 'Open'),
            array($this, 'Close'),
            array($this, 'Read'),
            array($this, 'Write'),
            array($this, 'Destroy'),
            array($this, 'Gc'));
        session_start();
    }

    public function __destruct()
    {
        session_write_close();
    }

    public function Open()
    {
        return true;
    }

    public function Close()
    {
        return true;
    }

    public function Read($sessionsId)
    {
        $this->stmt = $this->prepare("SELECT * FROM `sessions` WHERE `id` = :sessionId");
        $this->stmt->bindParam(":sessionId", $sessionsId);
        $this->stmt->execute();
        return $this->stmt->fetchAll();
    }

    public function Write($sessionsId, $sessionsData)
    {
        $this->stmt = $this->prepare("REPLACE INTO `sessions`.`sessions` 
        (`id`, `access`, `data`) 
        VALUES 
        (:sessionId, NOW(), :sessionValue)");
        $this->stmt->bindParam(":sessionId", $sessionsId);
        $this->stmt->bindParam(":sessionValue", $sessionsData);
        $this->stmt->execute();
    }

    public function Destroy($sessionsId)
    {
        $this->stmt = $this->prepare("DELETE FROM `sessions`.`sessions` WHERE `id` = :sessionId");
        $this->stmt->bindParam(":sessionId", $sessionsId);
        $this->stmt->execute();
    }

    public function Gc()
    {
        $this->stmt = $this->prepare("DELETE FROM `sessions`.`sessions` WHERE `access` < NOW() - INTERVAL 1 HOUR");
        $this->stmt->execute();
    }
}

现在上面的代码似乎工作得很好,唯一的问题是当我在数据库中写一个 session 时,我得到以下插入:

从 mysql 转储

CREATE TABLE IF NOT EXISTS `sessions` (
  `id` varchar(32) NOT NULL,
  `access` datetime NOT NULL,
  `data` text NOT NULL,
  UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `sessions` (`id`, `access`, `data`) VALUES
('lhig71coed8ur81n85iiovje37', '2011-07-25 15:37:57', '');

如您所见,未插入 session 的值,我只获取 session ID。 在 var_dump($sessionsData) 上我得到:

"name|s:6:"Bogdan";"

对于 var_dump($sessionsId) 我得到:

lhig71coed8ur81n85iiovje37

你能帮忙吗?我没有得到任何错误检查 xampp 日志设置显示错误报告我知道的一切,即使在 php.ini 中仍然没有错误任何使用甚至 try catch block 。非常感谢您阅读本文并帮助我。

最佳答案

我在您的实现中发现了一个缺陷,该缺陷会导致删除所有 session 数据:

return $this->stmt->fetchAll();

public function Read($sessionsId)

该函数必须返回一个字符串,在您的例子中是来自 data 字段的数据。

但您要返回一个数组(看起来像 - 不能具体说明,因为实际数据库是隐藏的,PDO/MySQLi?)。

然而,反序列化 session 数据(参见 session_decode())很可能会失败,因此 session 数据将变为空,然后再次保存(作为空字符串)。

这应该是您遇到问题的原因。通过从数据库返回字符串数据来修复它。


除此之外,我怀疑是某种编码问题,但我不完全确定是不是由它引起的。但只需考虑以下几点:

session 数据是二进制数据,不是文本。您可以相应地更改表定义和访问权限。在 MySQL 中有 BLOB Type为此,bindParam() PDO::PARAM_LOB 数据类型说明符可能会有所帮助。

这种类型的更改可能会解决您的问题。否则,它将确保您存储的数据未被更改,这在任何情况下都是您想要的。坚持对 session 数据进行二进制安全处理。

关于php - 数据库 session 处理程序问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6817652/

相关文章:

用于分页的 php 示例脚本

php - 通过多维数组循环出现问题

php - 我怎样才能结合这个查询?

mysql - 对表中的增量求和的sql查询

c# - 如何在 ASP.NET 中获取 session 状态对象的集合?

php - 如何使用 Codeigniter 获取数组值

php - 关闭浏览器可以终止服务器上的 PHP 脚本吗?

MySQL:不同的评估命令行和 mysql 控制台

javascript - 在所有页面中维护 session 信息不起作用

php - str_replace 和 preg_replace 尝试?