【问题标题】:Check if PHP session_id is in use检查 PHP session_id 是否正在使用
【发布时间】:2011-09-06 14:35:46
【问题描述】:

我正在构建一个网络应用程序,用户可以上传某些文件并通过网络应用程序界面处理它们。我需要在用户会话期间存储这些文件。我正在为每个用户创建一个文件夹,使用 session_id 作为文件夹名称并将文件存储在其中。

问题:没有任何迹象表明用户离开了我的站点并且会话即将停止使用。我需要一个清理脚本来获取每个文件夹的名称并检查 session_id 是否仍然处于活动状态,以便删除未使用且现在无法访问的文件夹。我该怎么做?

【问题讨论】:

  • “正在使用”是一个艰难的...“过期”会更容易测试。如果您正在寻找过期会话,这个线程有一个非常完整的答案:stackoverflow.com/questions/520237/…
  • @ecchymose “过期”是我的意思。 “未使用”和“已过期”有区别吗?无论如何,我会检查那个链接。
  • 我所说的“未使用”的意思是,您无法真正知道用户是否离开了计算机,正在与他的朋友交谈,或者只是被alt-tab...您只能知道一个会话“已死”或已过期(您可以设置限制),但您无法知道用户是离开计算机 5 分钟还是 5 天。对我来说,这取决于你想做的事情有很大的不同;-)
  • @ecchymose 您提供的链接正在讨论一个完全不同的问题。我想获取一个我知道在某个时候使用过的 session_id 并检查 PHP 是否仍然认为 session_id 处于活动状态(=未过期)。我将为一堆 session_id 执行此操作,而不是在会话中。
  • 哦!但是你必须做几乎相同的事情,但在会话之外。将“sess_id/expire date”对存储在某个数据库或 txt 平面文件中(最坏情况)...

标签: php sessionid


【解决方案1】:

如果您有权访问服务器的 crontab 或计划任务,您可以创建一个只允许在本地执行的 php 文件,该文件检查数据库中所有会话的到期日期/时间值。每次用户更新此到期日期/时间值时,都会将其更新为他们的下一个超时值(+30 分钟等)。

您的计划任务/crontab 将找到所有空闲的用户并清理他们留下的烂摊子而无需注销。我不建议让您的计划任务/crontab 运行得太频繁。至少让重复发生间隔几分钟,以适应您的情况。

【讨论】:

  • 这就是问题所在!我如何访问这个“数据库”?
  • 我假设您的 PHP 页面已经能够使用 mysqli_connect(或您的数据库类型所需的任何资源连接器)进行连接。现在,如果您有计划的任务/cronjob,您可以设置脚本以使用您为清理过程创建的 PHP 页面执行 PHP 二进制文件(Windows 中的 php.exe)。
  • 我说的是 PHP 会话!它们没有存储在某些 MySQL 数据库中!
【解决方案2】:

您遇到的问题与您拥有自定义会话文件目录时发生的问题基本相同(在不太复杂的级别上)。你也需要自己清理它。该过程也称为垃圾收集。

这通常通过在服务器端运行一个看门人作业来检查过时的会话文件,或者在您的示例中,检查过时的会话目录(这可以是一个 cron 作业)来完成。

这就是它的工作原理:

大多数文件系统存储文件的创建日期和最后访问日期。因此,如果会话超时,则 X 小时内不再使用它。因此,您可以放心地假设,如果在过去 X 小时内未访问会话文件,则该会话已失效,并且可以安全地删除所有“旧”于此时间的文件。

工作完成。对于您的目录,您可能希望在其中添加一个文件,用作测试文件来跟踪访问时间。

php 手册有一些例子:http://www.php.net/manual/en/session.configuration.php#ini.session.save-path(查找 mod_files.sh 脚本)

【讨论】:

    【解决方案3】:

    我发现这很有帮助/我认为它解决了您的问题:

    Best place to store large amounts of session data

    【讨论】:

      【解决方案4】:

      我也遇到过同样的问题。我的解决方案是检查会话文件:

      <?php
      // clean-up script.  Get cron/windows task scheduler to run this every hour or so
      
      // this is the path where PHP saves session files
      $session_path = ini_get('session.save_path');
      
      // this is the directory where you have created your folders that named after the session_id:
      $session_files_dir = '/path/to/your/save/dir';
      
      // loop through all sub-directories in the above folder to get all session ids with saved files:
      
      if ($handle = opendir($session_files_dir)) {
      
          while (false !== ($file = readdir($handle))) {
      
              // ignore the pseudo-entries:
              if ($file != '.' && $file != '..') {
      
                  // check whether php has cleaned up the session file
                  if (  file_exists("$session_path/sess_$file")  ) {
                      // session is still alive
                  } else {
                      // session has expired
                      // do your own garbage collection here
                  }
      
              }
          }
      
          closedir($handle);
      }
      
      ?>
      

      请注意,这假定session.save_handler ini 设置设置为"files"session.save_path 设置没有目录级前缀(即不匹配正则表达式/^\d+;/)并且php 的自动会话垃圾收集已启用。如果上述任何一个假设都不成立,那么您无论如何都应该实施手动会话垃圾收集,因此可以将您的清理代码添加到其中。

      这还假设$session_files_dir 中的唯一文件是您的每个会话文件夹,并且它们都以其关联的 session_id 命名。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-07
        • 1970-01-01
        • 1970-01-01
        • 2011-12-31
        • 2023-03-14
        • 2011-06-12
        • 1970-01-01
        • 2011-09-30
        相关资源
        最近更新 更多