PHP会话的数据在页面重新加载之间不一致 - 但会话ID是相同的

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP会话的数据在页面重新加载之间不一致 - 但会话ID是相同的相关的知识,希望对你有一定的参考价值。

我的一些php代码有一个非常奇怪的问题。我打开了错误报告,也没有出现任何问题。

基本上我有一个将数据推送到$ _SESSION []的表单。代码是:

<?php 
session_start();
$_SESSION['contact']['name'] = $_GET['name'];
$_SESSION['contact']['email'] = $_GET['email'];
$_SESSION['contact']['question'] = $_GET['question'];

session_write_close();
header('Location: confirm.php');
exit;
?>

这很有效。但是,完全随机的confirm.php将会或不会收到此数据。如果我多次刷新,我有时会得到数据,有时候不会。

这是确认代码:

<?php
ini_set('display_errors', 'on');
error_reporting(-1);

session_start();

print "SeshID:" . session_id() . "<br>";
print "CookieID:" . $_COOKIE['PHPSESSID'] . "<br>";
print "Status" . session_status() . "<br>";
print "Loc" . session_save_path() . "<br>";
print "Cookie";
print_r(session_get_cookie_params());
print "<br>Data:<br>";

print_r($_SESSION);
?>

再次,没有错误。没有任何东西看起来显然是错误的。

奇怪的是,有时当我刷新确认页面时,我会得到一个空的“Array()”。有时我会得到“Array([contact] => Array([question] => test [name] => [email] => test@test.com))”因为看似没有理由......

我之间没有运行其他脚本 - 只有上面检查会话内容的脚本(确认)需要重新运行,只有数据以某种方式改变。我运行表单几次,然后这个检查脚本,它完全不一致。会话和cookie ID永远不会更改,并且始终相同

我缺少一些PHP设置吗?我真的很奇怪,这些似乎正在剔除被覆盖的旧数据。

答案

Solved!

我将为遇到同样问题的人发布自己的答案。感谢帮助我发现这些内容的人们!

The Problem

问题是服务器使用群集或分发网络,Azure,以提供PHP文件。

第一次调用将会话数据写入机器1,然后确认从机器2读取,机器2没有正确的信息。在群集中,/ tmp通常不会被镜像,这就是会话数据的存储位置。与您的群集管理员讨论此事。 - 巴特弗里德里希斯

似乎正在发送表单并将会话变量存储在服务器1上,但是拉取会话数据的页面是服务器2,服务器3,有时是服务器1 - 因此看到先前提交的偶然行为和偶尔正确的数据的奇怪行为。

The Fix

这里有两种可能的修复方法。一:

会话存储目录未在所有服务器上进行镜像

在这种情况下,通过更改php.ini中的“session.save_path”或使用来更改会话目录

session_save_path(dirname(__FILE__). '/sessions/');

在调用session_start()之前,在受影响的文件的顶部(这是我们站点中使用会话的唯一部分,因此这是为了进行良好/脏修复)。

这里的要点是将其更改为一个目录,该目录肯定会在群集中的每个服务器上进行镜像。

会话以另一种未镜像的方式保存

在我的实际情况中,我发现我的会话处理程序是问题。通过使用

phpinfo();

我发现我的session.save_handler是“wincache”,这是一个加速PHP的插件。其中一种方法是使用共享内存或其他方式来加速会话数据的加载。

无论哪种方式,这不适合我的设置,我修改它只需更改变量使用默认值:'files'。

同样,最好的方法是使用你的php.ini并将session.save_handler设置为“files”,但我无法访问该文件,所以,我再次使用了两个标题中的调用session_start()之前的文件。

ini_set("session.save_handler", "files");

我不推荐这个,因为你知道它会在后面出现并在后面咬你,当一个新的开发人员进来而你忘记了 - 最好改变你的.ini

无论如何,就是这样。

谢谢大家的帮助!

在旁边

许多服务器解决方案(如Azure)实际上都提供了自己的插件和会话处理程序,专门用于抵消这种情况。如果可能的话,你当然应该使用它们!

另一答案

在刷新页面之后,会话仍然经过身份验证,但是我们丢失了我们手动添加的内容,尝试使用此指令(this.set('session.X','Y'));

以上是关于PHP会话的数据在页面重新加载之间不一致 - 但会话ID是相同的的主要内容,如果未能解决你的问题,请参考以下文章

PHP会话系统脚本重新加载页面没有消息[重复]

重新加载页面,保持会话

php 表单 - 2 个按钮(一个用于销毁会话并重新加载页面,一个用于进入下一页)

仅在 Angular SPA 中的页面加载之间缓存会话数据

php会话变量不一致

在页面重新加载/刷新时重置会话?