【发布时间】:2021-06-17 19:35:55
【问题描述】:
我试图了解 PHP 会话处理程序,更准确地说是 SessionHandlerInterface::read 的返回值。
The doc 状态(强调我的):
返回读取数据的编码字符串。 如果没有读取任何内容,则必须返回 false。请注意,此值在内部返回给 PHP 进行处理。
但是,the documentation of the SessionHandler class 和其他实现中使用的示例(例如 Symfony 的 PdoSessionHandler)似乎在无法读取任何内容时(例如第一次连接到主机时)返回一个空字符串。
为了说明这一点,我编写了一个简单的测试(该类继承自SessionHandler,而不是实现整个SessionHandlerInterface,为了简单起见——我知道不推荐这样做,而且这个例子也没用:它只是为了显示问题):
<?php
define('RETURN_VALUE', false);
class SimpleSessionHandler extends SessionHandler
{
public function read($id)
{
$data = parent::read($id);
if (!$data) {
return RETURN_VALUE;
} else {
return data;
}
}
}
$handler = new SimpleSessionHandler();
session_set_save_handler($handler, true);
$res = session_start();
print_r($res);
echo("Done");
当使用 false 作为返回值时,我得到一个 PHP 错误 (Warning: session_start(): Failed to read session data),而当我使用 ''(空字符串)时,它就像一个魅力。
我错过了什么?
我在 Fedora 33 下使用 PHP 7.4.20。
【问题讨论】:
-
docs of SessionHandler 还说:“警告该类旨在公开当前内部 PHP 会话保存处理程序,如果您想编写自己的自定义保存处理程序,请实现 SessionHandlerInterface 接口而不是从 SessionHandler 扩展”。但是我认为没有必要返回您自己的值,您也可以
return parent::read($id); -
除了我的第一条评论之外,我得出的结论是,继承类并一对一地采用覆盖方法是没有意义的。因此,您的 SimpleSessionHandler 类在其当前格式下没有任何意义。需要自定义会话处理程序还有其他原因,例如在数据库中存储会话时。
-
正如我所说,这个例子是为了说明:它没有任何用处,我选择从
SessionHandler继承,尽管文档为了简单起见(否则,代码将是 5 次)更长)。这是基于SessionHandlerInterface的尝试的简化版本来显示问题。我会说得更清楚。 -
如上所述,
If nothing was read, it must return false从这里我认为这意味着,如果会话文件未打开或文件不可读或在这种情况下抛出任何错误/异常read方法应该返回 false,但是如果文件已打开且可读但为空,则应返回empty字符串而不是false -
这是我的预期,但问题是您第一次连接时,会话文件不存在。所以按照文档,我们应该返回
false但在这种情况下,PHP 不会打开会话。