我的自动重定向登录页面的方法在PHP中正确吗?
我有一个社区网站,一个用户可以有很多朋友。当显示他的所有朋友时,我想包括他的朋友是在线还是离线 我的方法是,当用户登录时,在状态列“online”上创建一个会话并更新users表。如果他单击注销按钮,那么我将把状态设置为“脱机”。如果他没有点击注销按钮就关闭浏览器怎么办?以下是我想做的:我的自动重定向登录页面的方法在PHP中正确吗?,php,session,logout,Php,Session,Logout,我有一个社区网站,一个用户可以有很多朋友。当显示他的所有朋友时,我想包括他的朋友是在线还是离线 我的方法是,当用户登录时,在状态列“online”上创建一个会话并更新users表。如果他单击注销按钮,那么我将把状态设置为“脱机”。如果他没有点击注销按钮就关闭浏览器怎么办?以下是我想做的: session_start(); if (!isset($_SESSION['LAST_ACTIVITY'])) { // initiate value $_SESSION['LAST_ACTI
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=$\u SESSION['userid']
?我认为这是行不通的。当用户关闭浏览器时,您在此处输入的代码将永远不会被调用
一种可能的方法是,每当用户调用页面时,保存用户上次在数据库中处于活动状态的时间。如果用户上次活动的时间超过5分钟,您可以将其视为脱机,并将其显示给其他用户
我认为phpbb3就是这样做的
当用户关闭浏览器时获取一个事件是很麻烦的,而且并不总是有效。我发现您的代码中有几个问题:
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分钟,如果为真,则在该用户尝试重新进入站点时立即断开他的连接 据我所知,您的解决方案是,即使用户最后一次访问该网站已经超过10分钟了,该用户仍被标记为在线
您应该在数据库中保存上次用户在您的站点上活动的时间。当用户查看好友列表时,您这次也会查看好友列表,并查看是否超过10分钟前,即好友处于非活动状态。最好的方法是为登录的用户存储活动时间。当他们导航到某个页面或执行某个操作时,用当前时间更新他们在数据库中的“上次活动”时间。如果此时间超出阈值(例如,15分钟),则可以将该用户分类为不再活动。在标题位置重定向后,明确地写下以下行:
die();
并非所有的用户代理(浏览器、web爬行器等)都会侦听您的重定向头。删除脚本是确保他们不会获取页面其余部分的唯一安全方法。如果您仅通过在线/离线专栏确定用户是否已注销,那么用户关闭浏览器窗口(不点击注销链接/按钮)仍将登录 这里的正常方法是跟踪用户何时在站点上移动,存储他们最后一次导航到页面的时间。然后,设置一个预定义的常量,确定是什么让用户处于活动状态(比如说在过去15分钟内浏览页面),然后在SQL查询中使用该常量来抓取访问用户的朋友以及在过去15分钟内访问过站点的每个用户 在将时间存储为datetime的SQL查询中(这是MySQL的查询),这可能类似于:
SELECT col1, col2, col3 FROM Users WHERE DATE_ADD(LastActive, INTERVAL 15 MINUTE) > NOW() AND UserIsFriendOfCurrentUser
当然,您的查询需要进行调整,以更好地适应您的设置,但希望您能理解。在我们的项目中,我们使用以下技术:
糟糕的是,选项卡式浏览器在同一窗口中为每个打开的选项卡使用相同的会话id。但我们的项目是一个游戏,不允许来自一个浏览器的多用户。实际上,当两个或多个用户尝试从一个浏览器的不同选项卡登录时,这种情况非常罕见。您不应该使用
$\u SESSION
存储上次活动时间。每次用户转到某个页面时,使用用户表中的当前时间更新名为last\u 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']
);
//...
数据库会话可能是管理谁在线和谁不在线的好方法。理论上,它们应该自行失效。我在我的博客上写了一篇关于它的指南,你可以在
这还增加了一个额外的好处,允许您在需要时远程终止用户会话:)这就是我要做的。但是如果用户再也没有回来呢?然后他再也不会加载另一个页面将自己设置为脱机。您应该将该脚本放在某个地方,每隔10分钟左右调用一次,可能由cronjob调用—您不需要cronjob。当其他人想知道他是否是唯一的时,只需检查他的活动。+1:为了一个好时机,偶尔禁用浏览器重定向,并注意它完全绕过了许多使用重定向安全的劣质身份验证系统。
SELECT
u.user_name, u.name, etc,
IF(
UNIX_TIMESTAMP() - UNIX_TIMESTAMP(u.last_activity) < 300,
1, 0
) as online
...
$friends = $db->query(/* above SQL */);
foreach($friends as $friend)
{
if($friend['online'] == 1)
// online specific stuff
else
// offline specific stuff
}