你好,我想了解 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/