如何设置会话的生命周期

27

如何在PHP中设置会话的生命周期?我想将其设置为只要请求存在就永久有效。该请求是AJAX请求。处理AJAX请求的我的PHP代码如下:

// AJAX.php
<?php    
session_start();

$_SESSION['counter'] = $_SESSION['counter'] + 1;

header('Content-type: application/json');    
echo json_encode(array('tick' => $_SESSION['counter']));
?>

以及 JavaScript:

$(document).ready(function() {            
function check() {
    getJSON('ajax.php');        
}

function getJSON(url) {                                
    return $.getJSON(
                url,
                function(data) {
                    $("#ticker").html(data.tick);
                }
           );
}

setInterval(function() {
    check();
}, 10000); // Tick every 10 seconds

});

每300秒会重置一次会话。

7个回答

42

PHP中的会话使用Cookie类型的会话,而在服务器端,会话信息经常被删除。

若要设置php中的生存时间,您可以在session_start之前使用函数session_set_cookie_params

session_set_cookie_params(3600,"/");
session_start();

举例来说,3600秒是一个小时,2小时就是3600*2=7200秒。

但是这是会话cookie,浏览器可以自己设置过期时间。如果你想保存大量的会话时间(例如记住登录状态),你需要在服务器上保存数据并在客户端上保存标准cookie。

你可以创建一个名为“Sessions”的表:

  • session_id int
  • session_hash varchar(20)
  • session_data text

在验证Cookie时,你可以在客户端保存“会话ID”和“哈希值”(用于安全性),并在服务器端保存会话数据。例如:

在登录时:

setcookie('sessid', $sessionid, 604800);      // One week or seven days
setcookie('sesshash', $sessionhash, 604800);  // One week or seven days
// And save the session data:
saveSessionData($sessionid, $sessionhash, serialize($_SESSION)); // saveSessionData is your function

如果用户返回:

if (isset($_COOKIE['sessid'])) {
    if (valide_session($_COOKIE['sessid'], $_COOKIE['sesshash'])) {
        $_SESSION = unserialize(get_session_data($_COOKIE['sessid']));
    } else {
        // Dont validate the hash, possible session falsification
    }
}

在发送数据之前,显然要保存所有的会话/session和cookie调用。


5
这似乎是一个简单问题的过度复杂解决方案。在您的配置文件或.htaccess文件中设置session.cookie_lifetime的值有什么问题吗?您提出的方式需要在每个需要session的PHP文件中添加附加代码。 - Francois Deschenes
2
在你的例子中,“604800”的过期时间应该是“time()+604800”,这是一个绝对引用。 - Ignacio A. Poletti
你可以在php.ini中将其设置为0...那就是永久的。 - M H
2
@Hanoncs 错了,session.cookie_lifetime 在 php.ini 中默认为 0,这意味着它是一个会话 cookie,而不是永久存在的。 - The Onin
你的代码中的 valide_session 函数是什么?它有什么作用? - Robert Sinclair
显示剩余2条评论

27

17

5

会话可以在您的php.ini文件或您的.htaccess文件中进行配置。请参阅PHP会话文档

您需要做的是在php.ini文件中查找session.cookie_lifetime行,并将其值设置为0,以便会话cookie在浏览器关闭之前有效。如果您无法编辑该文件,则可以在.htaccess文件中添加php_value session.cookie_lifetime 0


1

由于大多数会话都存储在COOKIE中(根据上述评论和解决方案),因此重要的是确保COOKIE被标记为安全COOKIE(前端C#):

myHttpOnlyCookie.HttpOnly = true;

并/或查看php.ini(自PHP 5.3以来默认为TRUE):

session.cookie_httponly = True

0

我没有看到这个在任何地方提到过,但是在PHP文件中设置ini_set('session.gc_maxlifetime', $max_lifetime);通常不会产生预期的影响,如果php.ini文件有一个更低的值,并且服务器托管多个域名/虚拟主机。如果您在X网站上有用户,并且在PHP文件中将maxlifetime设置为10秒(这不是真实值,仅供示例),然后在php.ini中将maxlifetime设置为5,则如果您有多个域名/虚拟主机,将发生一些有趣/意外的事情。

当第二个用户访问一个没有在其PHP文件中设置ini_set('session.gc_maxlifetime', $max_lifetime);并且默认为php.ini的站点时,这将导致PHP的垃圾回收使用5秒而不是10秒作为maxlifetime触发,从而删除了本应至少持续10秒的用户会话。

因此,这个设置几乎永远不应该放在PHP文件本身中,而应该在vhost条目中,如果您的设置具有此功能并且符合此类型的场景。唯一的例外是,如果您的服务器只托管一个网站/vhost,那么它的PHP文件将始终覆盖php.ini。

这是因为所有站点都使用相同的tmp目录来存储会话数据。另一种缓解解决方案是为每个虚拟主机设置会话tmp目录。另一种(不建议的)解决方案是通过将其设置为0,完全禁用php.ini中的session.cookie_lifetime

值为0表示“直到浏览器关闭”。默认为0。另请参见session_get_cookie_params()和session_set_cookie_params()。 - Lepy

-4
只要用户不删除他们的cookies或关闭浏览器,会话就应该保持存在。

9
不正确!一点也不正确。服务器端的会话和cookie都将过期。 - bytecode77
抱歉,那是不正确的。会话变量将过期。 - joe_evans

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接