4

我陷入了一个$_SESSION问题,而$_SESSION随机丢失了它的数据。

我有一个包含不同页面的表单,用户有特定的时间来浏览所有页面。

所以我在第一页上设置了一个会话变量并在其他页面上检查它。

开始.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');

整个系统在本地安装、开发服务器和测试服务器上运行良好。在生产服务器上,我在不同的时间超时。它从 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
  • 会话在计算页面上设置,超时可能发生在每个页面(计算、表单、摘要)
  • 我从生产服务器获取了 php.ini 并将其放入我的本地工作区。在更改了一些路径(extensions-path、session.save_path、tmp-path)之后,它在我的本地安装中运行良好。
  • 协议是所有页面都相同
  • 重新创建会话(通过$tmpsession_destroy()session_create())没有帮助
  • 单前端,无负载均衡器(只需一个 apache)
  • 会话文件以某种方式被删除

添加一些输出并重新测试后,我得到以下信息:

  • 我加载页面(第一步)
  • 我通过表格到任何步骤(计算/表格/摘要)
  • 页面加载时$_SESSION

    array ( 'STARTED' => 1338298801, 'S_SID_' => '41554681145546', 'S_LC_' => 'de', 'version_testing' => 1, )

  • 我每三十秒重新加载一次该页面

  • 至少在 3 分钟后(也可能是 30 秒)我得到超时并且$_SESSION是:

    array ( )

  • 如果我在第一页上尝试这个,我会在 中得到一个新值$_SESSION,因为 sessiondata 是空的并且自动设置为新值。

  • 要记住:在测试/开发环境中,会话数据仍然存在,即使超时发生在 20 分钟后。

  • 首先更改 session.save_path 似乎有效(会话持续至少 24 分钟)。但是一小时后,还是同样的问题。没有会话持续超过 4 分钟。

发现问题(但还没有解决方案)
今天我获得了对生产服务器的访问权限,我发现,带有 Session-Data 的文件夹在 3-5 分钟后被清理了。没有文件的时间戳超过 3 分钟。如前所述,PHP 已正确设置(GC 生命周期),我没有找到任何 Windows 作业,或者类似的东西正在删除这些文件。由于 PHP.ini 设置正确,我将尝试通过数据库处理会话。

感谢帮助

4

3 回答 3

3

在这种特定情况下起作用的是:

另一个网站在同一台服务器上托管,但在不同的虚拟主机中。这个网站使用了一个“init.php”,每次请求都会被调用。它包含将 gc_maxlifetime 设置为 0 并随后开始会话的行。因此,在某些请求下,所有会话数据都被第二个网站随机清除。

在测试和开发上这不是问题,因为这两个环境并没有太多使用......

于 2012-05-31T09:38:23.410 回答
1

It's a common behavior I've seen multiple times when a PHP website is hosted on multiple frontend with a load balancer. As PHP store sessions on the filesystem by default, depending on which front you are, you have one or another session started.

The easy solution is to store your sessions to database, and even if I'm wrong about the load balancer, you should try to read the session data directly on the filesystem, checking what happends exactly (is PHP removing data? Is the data still here but another session token is generated? etc...).

于 2012-05-29T14:09:47.053 回答
0

乍一看(没有更多信息),您的会话似乎是在实际开始时间之前开始的。这无疑会导致这个问题。如果这可能是问题,试试这个。

$tmp = $_SESSION;
session_destroy();
session_start();
$_SESSION = $tmp;
$_SESSION['started'] = time();

此外,如果您正在访问子域等,您的会话将不存在。它仅存在于它设置时所在的确切域。

提供更多信息也可能会有所帮助。存在问题的页面的 URL。在页面上添加一些var_dump($_SESSION),并在您逐步完成时查看它的输出。当你注意到一个变化时,弄清楚它在哪里以及为什么会发生变化。

于 2012-05-25T15:06:14.233 回答