如何覆盖从文件读取的PHP会话



为了工作,我正在将一个大型自定义PHP程序从PHP v5.6升级到7.4,我已经接近尾声,但在会话开始和注销后,我一直看到会话读取警告(可能是因为生成了一个新会话来加载后续登录页面(。

Warning session_start(): Failed to read session data: user (path: /var/lib/php/session)

在你进一步阅读之前,让我明确一点程序不将会话数据存储在文件中我试图解决的问题不是文件权限问题。我的理解是,您可以使用PHP的内置会话处理,参考它的.ini配置session.save_handlersession.save_path,或者通过实现session_set_save_handler()函数来覆盖它们。这个应用程序使用第二个选项,并使用传递到session_set_save_handler()函数中的可调用函数实现自己的MemCached会话处理,除了上面的警告之外,这似乎运行得很好。

.ini配置是在不同的时间设置的,如下所示,这导致了不同的";局部值";以及";主值";在php信息页面中。

session.save_handler = "files"
session.save_path = "/var/lib/php/session"
session.save_handler=
session.save_path=
session.save_handler = "custom_handler"
session.save_path = "/"
# commented out
;session.save_handler = "files"
;session.save_path = "/var/lib/php/session"

然而,它们仍然允许发出此警告错误,只是会话无法从中读取数据的文件路径不同(在这种情况下,这无关紧要,因为应用程序没有在其中写入会话数据(。

更新:

"读取"函数处理程序:

public function read($sessionId)
{
if(isset($GLOBALS['sess']))
{
return $GLOBALS['sess'];
}
$sessionKey = self::formatSessionKey($sessionId);
$data = SV_GETMEMCACHED()->get($sessionKey);
$GLOBALS['sess'] = $data;
$GLOBALS['sess_hash'] = md5($data);
return $data ?: '';
}

<更新>

我有一些问题PHP文档和我的研究都没有解决。

首先,session_set_save_handler()是否覆盖save_handlersave_path配置,或者它们是否以某种方式协同工作?(后者似乎是这样(有人能描述一下这些不同配置选项之间的动态吗?(我基本上理解它们,但我显然不知道它们是如何相互作用的,因为我在实现我们自己的处理程序功能时收到了这个警告。(

第二,当我们为session_set_save_handler()实现"读取"功能时,我们被指示返回会话数据或空字符串。返回一个空字符串是否会提示PHP尝试通过.ini配置的方法读取会话数据?如果是这样的话,我可以抑制它,或者将PHP配置为不这样做,不使用会话数据的备用读取源吗?

第三,在程序开始时执行一次session_set_save_handler()是否足以运行整个脚本?我的前任曾多次召集它,例如在一次会议被破坏时。是否存在否定、绕过或无效session_set_save_handler()第一次执行时设置的任何事件或操作?是否考虑了从何处调用它的上下文/范围?或者,仅仅在session_start()之前调用/设置它就足够了吗?

感谢您的任何见解或问题,可能会得到答案。

在一位顾问的帮助下,我终于建立了连接,将同一请求中的重复会话访问缓存在$GLOBALS数组中(这可能是显而易见的(,并且这有一个允许不需要的值的快捷返回语句。

顾问建议对代码进行重组,使其只有一个返回点,这是足够公平的,并且可能避免了这种盲点/脑洞。

我确实进行了重组,就像这样。

public function read($sessionId)
{
if(!array_key_exists('sess', $GLOBALS))
{
$sessionKey = self::formatSessionKey($sessionId);
$GLOBALS['sess'] = GETMEMCACHED()->get($sessionKey);
}

// SESSION READS _MUST_ RETURN A VALID SESSION STRING, OR AN EMPTY STRING
$sessionData = $GLOBALS['sess'] ?: '';
$GLOBALS['sess_hash'] = md5($sessionData);
return $sessionData;
}

最新更新