我的自动重定向登录页面方法在PHP中是否正确?

时间:2009-05-20 15:08:33

标签: php session logout

我有一个社区网站,用户可以拥有很多朋友。在展示他的所有朋友时,我想包括他的朋友是在线还是离线。

我的方法是,当用户登录时,在状态列“在线”上创建会话并更新用户表。如果他点击退出按钮,那么我将状态设置为“离线”。如果他在没有点击退出按钮的情况下关闭浏览器怎么办?这就是我想要做的事情:

session_start();
if (!isset($_SESSION['LAST_ACTIVITY'])) {
    // initiate value
    $_SESSION['LAST_ACTIVITY'] = time();
}
if (time() - $_SESSION['LAST_ACTIVITY'] > 3600) {
    // last activity is more than 10 minutes ago
    session_destroy();
    //direct to a php, say this user is idle and thus status = offline
    header("location: update_status.php?user=".$_SESSION['username']."&status=offline");
    // den redirect them to login page
} else {
    // update last activity timestamp
    $_SESSION['LAST_ACTIVITY'] = time();
}

这是一种合适的方式吗?


编辑:

如果有一个简单的示例代码,如何检查用户何时在线并在用户访问页面时进行更新,将会很有帮助?

我是否需要在每个链接中加入php?user=$_SESSION['userid']

9 个答案:

答案 0 :(得分:5)

如果您确定用户是否已注销,只需通过您的在线/离线列 - 那么用户关闭其浏览器窗口(无需点击您的注销链接/按钮)仍将登录。

此处的常规方法是跟踪用户何时在您的网站上移动,存储导航到网页的最后时间。然后设置一个预定义的常量,使用户处于活动状态(比如在最近15分钟内浏览你的页面) - 然后在SQL查询中使用它来抓取每个访问者的朋友并且一直在该网站在过去15分钟内。

在SQL查询中,您将时间存储为日期时间(这是MySQL的查询),这可能类似于:

SELECT col1, col2, col3 FROM Users WHERE DATE_ADD(LastActive, INTERVAL 15 MINUTE) > NOW() AND UserIsFriendOfCurrentUser

当然,您的查询需要进行调整以更好地适应您的设置,但希望您明白这一点。

答案 1 :(得分:4)

在我的意见中,这不起作用。当用户关闭浏览器时,您放在此处的代码将永远不会被调用。

一种可能的方法是在用户调用页面时保存用户上次在数据库中处于活动状态。如果用户上次活动比5分钟之前的时间长,您可以将他视为离线,并将其显示给其他用户。

我认为phpbb3这样做......

当用户关闭浏览器时获取活动很重,但并不总是有效。

答案 2 :(得分:2)

标题位置重定向后,请务必将此行:

die();

并非所有用户代理(浏览器,网络蜘蛛等)都会侦听您的重定向标头。杀死脚本是唯一可以确保它们无法访问页面其他部分的安全方法。

答案 3 :(得分:0)

我在您的代码中看到了一些问题:

if (time() - $_SESSION['LAST_ACTIVITY'] > 3600) {
  // last activity is more than 10 minutes ago
  session_destroy();
  //direct to a php, say this user is idle and thus status = offline
  header("location: update_status.php?user=".$_SESSION['username']."&status=offline");
}

在这段代码中你破坏了会话,然后从你刚刚销毁的会话中获取用户名。

顺便说一句,如果我理解你的问题,你就不会得到这个代码的预期行为。

您检查用户是否只是访问您的站点(您启动的会话的所有者)已超过10分钟的空闲状态,如果为真,您现在断开他并尝试重新进入该站点。

答案 4 :(得分:0)

据我所知,您的解决方案是用户仍然标记为在线,即使上次用户在网站上的时间超过10分钟。

您应该在数据库中保存用户上次访问您网站的时间。当用户查看朋友列表时,您也会得到这次,看看是否超过10分钟前,即朋友处于非活动状态。

答案 5 :(得分:0)

执行此操作的最佳方法是为登录用户存储活动时间。当他们导航到页面或执行操作时,使用当前时间更新数据库中的“上次活动”时间。如果此时间超出阈值(例如,15分钟),则可以将用户归类为不再有效。

答案 6 :(得分:0)

在我们的项目中,我们使用这种技术:

  
      
  1. 登录后的每个用户都与会话ID相关联。
  2.   
  3. 浏览器通过计时器发送带有AJAX的“活动请求”。
  4.   
  5. 轻量级服务器端脚本更新DB中的最后一项活动,进行搜索   用户按会话ID。
  6.   
  7. cronjob更新所有超时用户,将其标记为离线   (实际上会话ID变空),和   为每个人执行注销例程   用户以避免损坏的数据   业务级别层。
  8.   

用户会怎么样? 在用户关闭浏览器之前 - 活动正在更新。关闭浏览器后,用户将超时并标记为脱机。当用户试图到达需要授权的任何位置时 - 我们尝试做的第一件事是通过会话ID在DB中找到他,如果没有 - 他只能看到登录表单(即include(); exit(); )。

不好的事情 - 标签式浏览器在同一窗口中为每个打开的标签使用相同的会话ID。但我们的项目是游戏,不允许来自一个浏览器的多用户。实际上,这是一个非常罕见的情况,2个或更多用户尝试从一个浏览器的不同选项卡登录...

答案 7 :(得分:0)

您不应使用$_SESSION来存储上次活动时间。每次用户转到某个页面时,都会使用users表中的当前时间更新名为last_activity的列:

<?php
session_start();

$userId = (int)$_SESSION['user']; // make sure it's an integer
$db->exec('
    UPDATE users 
    SET last_activity = NOW() 
    WHERE id = ' . $_SESSION['id']
);
//...

当您检索朋友列表时,添加一个if语句以检查它们是否在线(这是MySQL版本):

SELECT 
    u.user_name, u.name, etc,
    IF(
        UNIX_TIMESTAMP() - UNIX_TIMESTAMP(u.last_activity) < 300, 
        1, 0
    ) as online
    ... 

300秒是5分钟。根据需要调整此项。然后你的朋友就可以这样访问:

$friends = $db->query(/* above SQL */);
foreach($friends as $friend)
{
    if($friend['online'] == 1)
        // online specific stuff
    else
        // offline specific stuff
}

答案 8 :(得分:0)

数据库会话可能是您管理谁在线以及谁不在线的好方法。从理论上讲,他们应该自己过期。我在博客上写了一篇关于它的方法,你可以在http://brennydoogles.wordpress.com/2011/09/06/taking-control-of-your-php-sessions-using-database-sessions/

阅读更多内容

如果您需要,还可以远程终止用户会话,这也有额外的好处:)