我陷入了 $_SESSION
问题,而 $_SESSION
随机丢失了数据。
我有一个包含不同页面的表单,用户有特定的时间来浏览所有页面。
所以我在第一页上设置了一个 session 变量,然后在其他页面上检查它。
start.php
<?php
session_start();
//Set Variable for Starting application
if (!isset($_SESSION['STARTED'])){
$_SESSION['STARTED'] = time();
}
app_init.php
<?php
session_start();
if ((!isset($_SESSION['STARTED'])) || (time() - $_SESSION['STARTED'] > MAX_TIMELIMIT)) {
echo '<!-- st: '.$_SESSION['STARTED'].'-->';
// Started Variable is not set or timelimit is over.
session_destroy(); // destroy session data in storage
session_unset(); // unset $_SESSION variable for the runtime
showTimeout('0'); // show timeout
}
之后的页面开始:
<?php
// get basic settings for applications
require_once (MODEL_PATH.'/app_init.php');
整个系统在本地安装、开发服务器和测试服务器上运行良好。在 Productionserver 上,我在不同的时间超时。它从 30 秒到 10 分钟不等。 MAX_TIMELIMIT
是 20 分钟。 $_SESSION['STARTED']
在这种情况下始终为空。在其他环境中,它已正确设置,即使在 20 分钟后出现超时也是如此。
附加信息:
- 不管我是尝试访问下一页还是只是重新加载实际页面,我总是会超时。
- 我已经在任何环境下检查了
php.ini
->session.save_path
设置正确,session.cookie_lifetime
为 0 且session.gc_maxlifetime
为 1440 - 磁盘空间充足(> 22 GB 可用空间)
- 每个文件都在同一台服务器上并具有相同的 url(除了指定表单步骤的最后一部分。看起来像这样:
host/some/path/calc -> host/some/path/form -> host/some/path/summary -> host/some/path/send - session 在计算页面上设置,超时可能发生在每个页面(计算、表单、摘要)
- 我从生产服务器获取了 php.ini 并将其放入我的本地工作区。更改一些路径(extensions-path、session.save_path、tmp-path)后,它在我的本地安装上运行良好。
- 协议(protocol)是所有页面都一样
- 重新创建 session (通过
$tmp
和session_destroy()
、session_create()
)没有帮助 - 单前端,无负载均衡器(只有一个 apache)
- session 文件以某种方式被删除
添加一些输出并重新测试后,我得到以下结果:
- 我加载页面(第一步)
- 我通过表格到任何步骤(计算/表格/摘要)
当页面加载时
$_SESSION
是数组 ( '开始'=> 1338298801, 'S_SID_' => '41554681145546', 'S_LC_' => 'de', 'version_testing' => 1, )
我每三十秒重新加载一次该页面
至少在 3 分钟后(也可能是 30 秒)我得到超时并且
$_SESSION
是:数组 ( )
如果我在第一页尝试此操作,我会在
$_SESSION
中获得一个新值,因为 session 数据为空并自动设置新值。记住:在测试/开发环境中, session 数据仍然存在,即使在 20 分钟后发生超时。
首先更改 session.save_path 似乎有效( session 持续至少 24 分钟)。但是一小时后,还是一样的问题。没有 session 持续超过 4 分钟。
已找到问题(但还没有解决方案)
今天我获得了对生产服务器的访问权限,我发现,带有 session 数据的文件夹在 3-5 分钟后被清理干净。那里没有文件的时间戳超过 3 分钟。
如前所述,PHP 已正确设置(GC 生命周期),我没有找到任何 Windows 作业或类似的东西正在删除这些文件。由于 PHP.ini 设置正确,我将尝试通过数据库处理 session 。
感谢帮助
最佳答案
在这种特定情况下有效的方法:
另一个网站托管在同一台服务器上,但位于不同的虚拟主机中。该网站使用了一个“init.php”,它在每次请求时都会被调用。它包含一行将 gc_maxlifetime 设置为 0 并在之后启动 session 。因此,在某些请求下,第二个网站随机清除了所有 session 数据。
在测试和开发上这不是问题,因为这两个环境没有那么多使用......
关于PHP 丢失 session 数据 -> session 文件删除得太快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10753800/