php $_SESSION 变量随机消失并重新出现
php $_SESSION variables disappear and reappear randomly
Preface: this is a "development" from an earlier question of mine, whose answers didn't solve my problem in the end. But through trying all the suggestions and also trying other stuff, I discovered that the real problem is something else, so I rephrase my question here
我有一个登录 page/system,多年来一直正常工作,让用户一直登录,直到 he/she 关闭浏览器 window 或手动注销。但最近,在闲置几分钟后,会话 cookie/s 似乎过期,导致用户自动注销。
不同的浏览器和不同的操作系统都会出现这种情况,PHP版本是5.6.29,最近改了(之前是5.5甚至5.3)。
我使用 session_start()
在每个页面上创建和刷新会话。登录脚本首先检查用户名和密码,并从数据库中获取一些其他用户数据。这些其他数据和成功登录状态保存在会话变量中,如
$_SESSION['username'] = $name;
$_SESSION['usertype'] = $type;
$_SESSION['login'] = "ok";
在其他页面上,我这样检查登录状态:
session_start();
if(($_SESSION['login'] != "ok") OR ($_SESSION['usertype'] != "xxx")) {
header("Location: ../login.php"); /* redirects to login page if conditions are not true */
exit;
}
登录有效,登录用户可以在一段时间内继续访问其他页面,但一段时间后(变化很大),he/she 似乎注销(即尝试打开另一个页面时重定向到登录页面)。
然后我注意到(在开发人员工具中)会话 ID cookie 在会话似乎已过期后保持相同的值(我曾想过,因为会话变量走了)。但是会话并没有过期,只是会话变量消失了。在我的测试中,我尝试在某些页面上回显其中一些变量,但我偶然发现,在它们已经消失(没有回显输出)之后,当我重新加载几分钟后,它们 重新出现 页面或更改到另一个页面。
这就是我目前陷入困境的地方:这怎么会发生,尤其是:我该怎么做才能防止这些变量玩捉迷藏?
(顺便说一句,我无权访问服务器设置 - 这是在共享网站空间上...)
这不是解决方案,只是对我在评论中写的案例的测试。你能试试这个吗?
<?php
$number = (int)$_GET["number"];
$temp_dir = "/tmp/lbtest123";
if (!is_dir($temp_dir)) {
if (!mkdir($temp_dir, 0777, true)) {
die("Can't create directory: $temp_dir");
}
}
file_put_contents($temp_dir."/".$number.".txt", "");
echo "<pre>\n";
print_r(glob($temp_dir."/*.txt"));
echo "</pre>";
将此复制到您的服务器。
它使用作为参数传递的数字在 /tmp/lbtest123 文件夹中创建文件。然后列出已经创建的文件。
用递增的数字调用它,持续的时间与您期望 "logout" 发生的时间相同。示例:
示例结果:
Array
(
[0] => /tmp/lbtest123/1.txt
[1] => /tmp/lbtest123/2.txt
[2] => /tmp/lbtest123/3.txt
[3] => /tmp/lbtest123/4.txt
)
我希望它在一段时间后显示如下内容:
Array
(
[2] => /tmp/lbtest123/4.txt
[3] => /tmp/lbtest123/5.txt
)
Array
(
[0] => /tmp/lbtest123/1.txt
[1] => /tmp/lbtest123/2.txt
[2] => /tmp/lbtest123/3.txt
[3] => /tmp/lbtest123/6.txt
)
对于任何感兴趣的人:
显然@Crouching Kitten 是对的 - 提供商的架构在负载均衡器或类似的东西后面有多台机器,对此我无能为力。
所以我接受了他的建议,现在将之前作为会话变量的所有内容(连同会话 ID)保存在我在该网站每个页面开头访问的数据库中。我还在其中保存了一个时间戳,它会随着包含相同会话 ID 的每个新查询进行更新,因此我可以设置一个 cronjob,每半小时清除一次过时的数据(超过 90 分钟 - 但该间隔可以是任何时间)。
Preface: this is a "development" from an earlier question of mine, whose answers didn't solve my problem in the end. But through trying all the suggestions and also trying other stuff, I discovered that the real problem is something else, so I rephrase my question here
我有一个登录 page/system,多年来一直正常工作,让用户一直登录,直到 he/she 关闭浏览器 window 或手动注销。但最近,在闲置几分钟后,会话 cookie/s 似乎过期,导致用户自动注销。
不同的浏览器和不同的操作系统都会出现这种情况,PHP版本是5.6.29,最近改了(之前是5.5甚至5.3)。
我使用 session_start()
在每个页面上创建和刷新会话。登录脚本首先检查用户名和密码,并从数据库中获取一些其他用户数据。这些其他数据和成功登录状态保存在会话变量中,如
$_SESSION['username'] = $name;
$_SESSION['usertype'] = $type;
$_SESSION['login'] = "ok";
在其他页面上,我这样检查登录状态:
session_start();
if(($_SESSION['login'] != "ok") OR ($_SESSION['usertype'] != "xxx")) {
header("Location: ../login.php"); /* redirects to login page if conditions are not true */
exit;
}
登录有效,登录用户可以在一段时间内继续访问其他页面,但一段时间后(变化很大),he/she 似乎注销(即尝试打开另一个页面时重定向到登录页面)。
然后我注意到(在开发人员工具中)会话 ID cookie 在会话似乎已过期后保持相同的值(我曾想过,因为会话变量走了)。但是会话并没有过期,只是会话变量消失了。在我的测试中,我尝试在某些页面上回显其中一些变量,但我偶然发现,在它们已经消失(没有回显输出)之后,当我重新加载几分钟后,它们 重新出现 页面或更改到另一个页面。
这就是我目前陷入困境的地方:这怎么会发生,尤其是:我该怎么做才能防止这些变量玩捉迷藏?
(顺便说一句,我无权访问服务器设置 - 这是在共享网站空间上...)
这不是解决方案,只是对我在评论中写的案例的测试。你能试试这个吗?
<?php
$number = (int)$_GET["number"];
$temp_dir = "/tmp/lbtest123";
if (!is_dir($temp_dir)) {
if (!mkdir($temp_dir, 0777, true)) {
die("Can't create directory: $temp_dir");
}
}
file_put_contents($temp_dir."/".$number.".txt", "");
echo "<pre>\n";
print_r(glob($temp_dir."/*.txt"));
echo "</pre>";
将此复制到您的服务器。 它使用作为参数传递的数字在 /tmp/lbtest123 文件夹中创建文件。然后列出已经创建的文件。
用递增的数字调用它,持续的时间与您期望 "logout" 发生的时间相同。示例:
示例结果:
Array
(
[0] => /tmp/lbtest123/1.txt
[1] => /tmp/lbtest123/2.txt
[2] => /tmp/lbtest123/3.txt
[3] => /tmp/lbtest123/4.txt
)
我希望它在一段时间后显示如下内容:
Array
(
[2] => /tmp/lbtest123/4.txt
[3] => /tmp/lbtest123/5.txt
)
Array
(
[0] => /tmp/lbtest123/1.txt
[1] => /tmp/lbtest123/2.txt
[2] => /tmp/lbtest123/3.txt
[3] => /tmp/lbtest123/6.txt
)
对于任何感兴趣的人:
显然@Crouching Kitten 是对的 - 提供商的架构在负载均衡器或类似的东西后面有多台机器,对此我无能为力。
所以我接受了他的建议,现在将之前作为会话变量的所有内容(连同会话 ID)保存在我在该网站每个页面开头访问的数据库中。我还在其中保存了一个时间戳,它会随着包含相同会话 ID 的每个新查询进行更新,因此我可以设置一个 cronjob,每半小时清除一次过时的数据(超过 90 分钟 - 但该间隔可以是任何时间)。