【问题标题】:Few questions about PHP sessions关于 PHP 会话的几个问题
【发布时间】:2012-01-26 19:31:39
【问题描述】:

我有几个关于 php 会话的问题:

  1. 由于 session.gc_maxlifetime 的默认值为 24 分钟,这意味着任何 未修改 24 分钟的会话文件都将被删除,并且会话将自动过期。

  2. 如果我在代码中使用session_destroy(),会话将被取消设置,但会话文件本身直到上次修改后的 24 分钟后才会被删除。

  3. 延长会话生命周期(超过 24 分钟)的唯一方法是将 session.gc_maxlifetime 延长到更大的值。

所有这些都是正确的,还是我弄错了?

此外,如果我将会话存储在数据库中(使用session_set_save_handler()),所有这些规则都适用于它们吗?

【问题讨论】:

    标签: php session session-cookies session-timeout


    【解决方案1】:
    1. 几乎。文件(会话)不会立即删除,由 session.gc_probabilitysession.gc_divisor 决定。

    2. 不,会话将过期,但会话文件的删除如前所述确定

    3. 这通常是正确的,但如果您要实现自己的会话处理程序,即使忽略 session.gc_maxlifetime 也可以更改会话到期的行为

    在 db 中存储会话不应更改这些规则,但如果您愿意,可以稍微延长它们。

    编辑:

    这大致就是你如何注册自己的会话处理程序(处理程序是一个类)然后用它做任何你想做的事情

    首先,假设我们有一个类,它将为我们的应用程序处理会话。

    class MySession {
      function open($save_path, $session_name) {
      }
    
      function close() {
      }
    
      function read($id) {
      }
    
      function write($id, $sess_data) {
      }
    
      function destroy($id) {
      }
    
      function gc($maxlifetime) {
      }
    }
    

    要在php中注册handler,只需要调用session_set_save_handler函数,在我们的例子中是这样的:

    // register the session handler
    $sess = new MySession();
    session_set_save_handler(array($sess, 'open'),
                         array($sess, 'close'),
                         array($sess, 'read'),
                         array($sess, 'write'),
                         array($sess, 'destroy'),
                         array($sess, 'gc'));
    

    请注意,实际上有更好的方法来注册处理程序本身,您甚至可以在类的构造函数中执行此操作,或者以许多其他方式。但我认为这不是重点。

    重要的是,尽管 PHP 为您提供了与其会话管理机制的标准行为相对应的所需变量,但您不必尊重它(我不建议这样做)。

    要回答下面的评论,忽略 maxlifetime 参数,您可以在 gc 方法中忽略它并使用您认为必要/正确的任何内容,例如(使用 db 伪代码):

    function gc($maxlifetime) { 
      $sql = "DELETE * FROM MySession WHERE lastAccess < NOW()-3600";
      // execute the query, say I have PDO instance in $dbh variable
      $dbh->execute($sql);
    }
    

    瞧,您自己完全绕过了 PHP 会话设置。

    【讨论】:

    • 感谢您的回复。还有一个问题:您能否在回复中详细说明第 3 点?目前我正在使用默认配置进行会话管理。我无法控制 php.ini,因为它是共享服务器,所以我无法修改 session.gc_maxlifetime。我正在考虑使用数据库来存储会话并独立控制每个会话的生命周期(通过使用记住我选项)。
    • 感谢您的解释。你让我开心:)
    【解决方案2】:
    1. 正确,session.gc_maxlifetime 会在会话到期时删除会话文件
    2. session_destroy 不会删除会话文件
    3. 是的,这是唯一的方法。在您可以使用 session.gc_divider 禁用垃圾收集并制作一个脚本来进行自己的垃圾收集之后,基于 Debian 的发行版实际上默认情况下会这样做。

    将会话存储在某个数据库中不会改变这些规则。

    【讨论】:

    • 感谢您的回复。我无法控制 php.ini,因为它是共享服务器,所以我无法修改 session.gc_maxlifetime。我正在考虑使用数据库来存储会话并独立控制每个会话的生命周期(通过使用记住我选项)。这可行吗?
    • 任何教程或示例都会有帮助:)。我实际上正在使用 Zend 框架,因此在数据库中存储会话很容易。问题是没有提到延长独立会话的生命时间。我认为 rememberMe() 函数可以解决问题,但它只会延长 cookie 的生命周期。
    • @Songo:将 gc_divider 更改为 0,这样 PHP 将不再尝试删除会话,在您应该添加一些 CRON 作业以按照您想要的方式清理会话之后。
    猜你喜欢
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    • 2011-08-24
    相关资源
    最近更新 更多