PHP会话超时

48

当用户登录时,我会创建一个会话:

$_SESSION['id'] = $id;

我该如何在X分钟后明确指定会话超时并使其执行函数或页面重定向?

编辑:我忘记提到我需要由于不活动而超时的会话。


9
可能是如何在30分钟后使PHP会话过期?的重复问题。 - Kzqai
8个回答

87

首先,存储用户最后一次发出请求的时间

<?php
  $_SESSION['timeout'] = time();
?>

在后续请求中,检查他们上一次请求是多久以前(在此示例中为10分钟)。

<?php
  if ($_SESSION['timeout'] + 10 * 60 < time()) {
     // session timed out
  } else {
     // session ok
  }
?>

22
如果您选择的时间长于PHPINI中默认的会话超时时间,那么在此之前会话可能会超时。默认情况下,超时时间通常不到一小时。如果您不希望客户端控制超时时间,您需要将此代码与session.cookie_lifetime的ini_set结合使用。此答案还未处理客户端删除其cookies的情况。 - Olhovsky
2
PHP默认值为'0',这意味着:"直到浏览器关闭"。如果浏览器删除了cookie,则$_SESSION['timeout']变量将首先不会被设置。然而,我跳过了所有其他的会话管理,因为这个问题只问超时。 - Jacco

46

当会话过期时,数据将不再存在,因此类似以下代码:

if (!isset($_SESSION['id'])) {
    header("Location: destination.php");
    exit;
}

会在会话不再活动时进行重定向。

您可以使用session.cookie_lifetime设置会话cookie的生存时间。

ini_set("session.cookie_lifetime","3600"); //an hour

编辑:如果您由于安全问题(而不是方便性)而将会话超时,请使用已接受的答案,正如下面的评论所示,这由客户端控制,因此不安全。我从未将其视为安全措施。


1
你需要移除$_SESSION['id']周围的引号。 - Victor Stanciu
尽管你不是被投票选中的答案,但你的解决方案似乎更安全。我的问题是,你是否需要在每个页面上设置会话超时时间?我想这是有道理的,因为你希望它每次重新启动。其次,你是否必须在每个页面上执行session_start才能获取会话数据,还是只需启动一次即可?谢谢。 - nagates
11
会话 cookie 生命周期存在一些问题,最明显的是它依赖于客户端来执行。Cookie 生命周期存在的目的是让客户端清理无用/过期的 cookie,而不是与任何安全相关的东西混淆。 - Jacco
@jacco:我也反对,给它踩个负评。这只是通过混淆来保证安全性。 - mark
"Session.cookie_lifetime" 指定客户端/浏览器 cookie 的生存期。如果您想设置服务器端的生存期,请使用 "session.gc_maxlifetime"。http://www.php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime - Nijboer IT
显示剩余2条评论

5

首先要检查会话是否已经创建,如果没有则创建一个。这里我设置了它只持续1分钟。

<?php 
   if(!isset($_SESSION["timeout"])){
     $_SESSION['timeout'] = time();
   };
   $st = $_SESSION['timeout'] + 60; //session time is 1 minute
?>

<?php 
  if(time() < $st){
    echo 'Session will last 1 minute';
  }
?>

2
<?php 
session_start();

if (time()<$_SESSION['time']+10){
$_SESSION['time'] = time();
echo "welcome old user";
}

else{
session_destroy();
session_start();
$_SESSION['time'] = time();
echo "welcome new user";
}
?>

2
<script type="text/javascript">
window.setTimeout("location=('timeout_session.htm');",900000);
</script>

在每个页面的页眉中,这对我进行站点测试非常有用(该站点尚未投入生产)。它所涉及到的HTML页面会结束会话,并提示用户需要重新登录。与使用PHP逻辑相比,这似乎是一种更简单的方法。

我希望能够听到有关这个想法的评论。我是否忽略了其中的任何陷阱?


2
如果您打开了多个具有相同站点的选项卡,则必须刷新它们所有以创建活动,否则,如果您继续在一个选项卡中工作,则其他选项卡将在超时后显示“timeout_session.htm”。这非常令人沮丧,特别是如果“timeout_session.htm”正在取消设置/销毁会话。=) - Alex G

1
回复内容存在敏感词^**$lifetime。
通过调用session_destroy来使cookie过期可能会产生不可预测的结果,因为它们可能已经过期。
在php.ini中进行更改也是有效的解决方案,但它会使整个域的过期时间变为全局,这可能不是您真正想要的 - 有些页面可能选择保留某些cookie。

0
    session_cache_expire( 20 );
    session_start(); // NEVER FORGET TO START THE SESSION!!!
    $inactive = 1200; //20 minutes *60
    if(isset($_SESSION['start']) ) {
$session_life = time() - $_SESSION['start'];
if($session_life > $inactive){
    header("Location: user_logout.php");
}
    }
    $_SESSION['start'] = time();

    if($_SESSION['valid_user'] != true){
    header('Location: ../....php');
    }else{  

来源: http://www.daniweb.com/web-development/php/threads/124500


1
仅仅通过谷歌搜索第一个答案并将其粘贴到Stack Overflow并不符合这个网站的宗旨。此外,session_cache_expire()与您的会话长度无关,所以您粘贴的答案包含了错误的信息。 - David Bradbury
默认情况下,Cookie 存储 session_id,如果 Cookie 过期,则客户端请求时无法访问 session_id。@DavidBradbury - LF00

0
<?php
session_start();
if($_SESSION['login'] != 'ok')
    header('location: /dashboard.php?login=0');

if(isset($_SESSION['last-activity']) && time() - $_SESSION['last-activity'] > 600) {
    // session inactive more than 10 min
    header('location: /logout.php?timeout=1');
}

$_SESSION['last-activity'] = time(); // update last activity time stamp

if(time() - $_SESSION['created'] > 600) {
    // session started more than 10 min ago
    session_regenerate_id(true); // change session id and invalidate old session
    $_SESSION['created'] = time(); // update creation time
}
?>

请确保在回答中添加注释并解释超时时间的添加位置和方式。 - Rias

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