如何在php中检测用户是不是已注销?

Posted

技术标签:

【中文标题】如何在php中检测用户是不是已注销?【英文标题】:How to detect if a user has logged out, in php?如何在php中检测用户是否已注销? 【发布时间】:2010-10-27 15:19:55 【问题描述】:

用户成功登录后,我将 login = true 存储在数据库中。但是,如何在不单击注销按钮的情况下关闭浏览器来检查用户是否已注销?另外,如何将10分钟未活动的用户重定向到登录页面?

我正在使用 phpmysql。任何帮助将不胜感激。

编辑: 对不起,如果我的问题不清楚。我确实使用 session 来存储他们是否登录。但是,现在我想将信息存储在数据库中,以便我可以在其他页面上显示它们的状态。假设 user1 有 3 个朋友。当显示他所有的朋友时,user1 想知道他的朋友是在线还是离线。这就是我要的。有什么建议吗?

【问题讨论】:

remove information from mysql table when user close his Browser的可能重复 【参考方案1】:

2017 年编辑:如今,您最好的选择是使用 websockets 来跟踪页面/站点上的存在。


您无法检测到用户何时关闭浏览器或使用 PHP 导航离开您的网站,而且这样做的 javascript 技术远不能保证毫无用处。

相反,您最好的选择是最有可能存储每个用户的最后活动时间。

在您的用户表中沿“last_activity”行创建一列。 每当用户加载页面时,将他们的 last_activity 更新为当前时间。 要获取谁在线的列表,只需在数据库中查询 last_activity 值比 10/20/任何分钟前更近的用户。

【讨论】:

我曾经在一个项目中使用过你描述的方法,效果很好。您甚至可以使用 mysql 日期和时间函数,例如 timediff() 和 (time_to_sec(timediff(now(), last_activity))) 来显示时间段(上次活动:15 分钟前)。 这样看来,如果每一个访问的页面都需要更新数据库,就会使数据库非常繁忙。有没有像 Gumbo 建议的那样轻松的方式?我不是很懂他的评论,不是很懂…… 如果您的网站太忙以至于每页的额外查询会使您的系统陷入困境,“谁在线?”页面将是如此之大以至于无论如何都没用。 Gumbo 的会话方法不适用于“谁在线?”页面。 @show_lol,为了防止数据库上的潜在负载,您可以跟踪上次更新数据库的时间。例如,如果距离上次数据库更新不到一分钟,则可能不需要再次更新。【参考方案2】:

您可以通过多种方式来执行此操作,我猜最多 2 种,其中一个打扰最后一个活动,您将它与使用 jQuery 来检查不活动状态相结合,即一段时间内没有鼠标或键盘事件,说大约 10 到 20 分钟,然后在确认空闲时间后,您对 php 文件进行 ajax 调用,该文件将更新您的数据库表,显示用户离线。

你可以从:

<script type="text/javascript">
idleTime = 0;
$(document).ready(function () 
//Increment the idle time counter every minute.
var idleInterval = setInterval(timerIncrement, 60000); // 1 minute

//Zero the idle timer on mouse movement.
$(this).mousemove(function (e) 
    idleTime = 0;
);
$(this).keypress(function (e) 
    idleTime = 0;
);
);

function timerIncrement() 
idleTime = idleTime + 1;
if (idleTime > 19)  // 20 minutes
    $.ajax(
     url: 'update_user.php',
     type: 'POST',
     datatype: 'json',
     data: someData
    );


</script>   

【讨论】:

【参考方案3】:

恕我直言,最好的方法是在每次更新用户记录时将上次活动时间戳存储在数据库中。注销或超时后(使用 cronjob 保持超时)只需将其设置为零值并用作标志。

$user = new User($user_id);
$user->logged_in = (bool)($last_activity > 0);

有时你需要说 smth。像“最后一次看到...”,然后离开最后一个活动,只需在您的用户表中添加一个布尔标志(tinyint)logged_in。

【讨论】:

【参考方案4】:

这是对“ceejayoz”之前所说的内容的扩展。

让用户定期 ping 服务并告知他们仍然登录。将上次 ping 时间存储在会话中。如果最后一次 ping 会话大于所述时间,则再次 ping 以告知用户仍然存在。

将收到 ping 的时间存储在数据库中。如果收到的最后一个 ping 大于 keeplive 阈值,则认为用户已离开站点。

以下是一些未经测试的示例代码,供您开始使用。您可以使用“PING__FREQUENCY”来控制用户活动更新 last_activity 列的频率。

define(PING_FREQUENCY,300); //5 mins
if (($_SESSION['lastPingTime'] + PING_FREQUENCE) > time()) 
    stillLoggedIn(); //execute a function to tell that the user is still logged in


function stillLoggedIn() 
    //Do SQL update to mark the last activity time for the user

【讨论】:

警告:如果您有大量用户,您可以通过这种方式对您的网站进行 DDoS 攻击 是的。顺便说一句,这不是我会做的事情。但仅作为原始帖子中描述的问题的解决方案提供。【参考方案5】:

存储用户每个活动的时间戳。如果该时间超过 10 分钟,请退出。

在 PHP 中,你可以这样做:

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();
 else 
    // update last activity timestamp
    $_SESSION['LAST_ACTIVITY'] = time();

可以在数据库上执行相同的操作。在那里,您甚至可以获得“当前”在线的用户列表。

【讨论】:

这是否适用于超过 1 个用户?如果我要列出 10 个用户,想查看 10 个用户在线,怎么做? opps,对不起.. 我知道,如果最后一次活动超过 10 分钟,我将重定向到一个 php 页面,告诉我的数据库该用户已注销?这是你的意思吗? cmets 描述了每个分支的含义。所以“last activity is more than 10 minutes ago”的意思是如果最后一个活动是10多分钟前就进入了这个分支,所以他是10多分钟不活动的。这对您的应用程序逻辑意味着什么是您的业务。 但是,如果您想获得“当前”在线用户的列表,您需要一个可以从任何地方永久访问的源。所以你最好使用数据库解决方案。 谢谢gumbo,但我不太明白你的意思。可以永久访问任何地方的源?抱歉,我对 php 很陌生,对 php 很陌生【参考方案6】:

您想知道是否可以检测用户是否关闭了浏览器。您可以使用 javascript,但我不会依赖它(因为 javascript 很容易禁用)但是您不能使用 PHP,因为 PHP 仅在您请求页面时运行。不是在页面打开时。

为了安全起见,您应该跟踪用户的最后一次活动,如果已经过了几分钟 (5/10),则假定该用户已经离开。如果他再次做某事(例如 6 分钟后),那么他就会重新上线。

【讨论】:

【参考方案7】:

AFAIK 您无法检查某人何时关闭浏览器窗口(或离开您的页面转到另一个页面),因此您需要按照上面其他人的建议检查活动。

【讨论】:

【参考方案8】:

如果您尝试跟踪“在线”用户,那么您可以考虑为单个用户使用会话,而不是将 login=true 存储在数据库中以向您或其他人显示他们的状态,而是存储最后一个活动时间给用户。当您提取在线用户列表时,创建您的 sql 查询以仅返回过去 10 分钟内具有“last_activity”的用户。

【讨论】:

【参考方案9】:

您会发现使用会话来监控登录状态会更好。

Read this information about sessions

【讨论】:

【参考方案10】:

您为什么不为此使用会话或 cookie 而不是将其插入数据库中。 您可以使用 setcookie() 函数设置 cookie,也可以使会话变为可用并将值存储在其中。

【讨论】:

【参考方案11】:

通常您会将此类信息放在会话中。

$_SESSION['user'] = "A user name";

然后当你想注销时:

session_destroy();

更多关于会话here 和tutorial 的信息。

【讨论】:

我知道。但是如果用户关闭浏览器呢?我的数据库仍然保持状态为 true 对吗?我想显示用户是在线还是离线。 状态应该是一个日期时间然后每次用户做某事你可以更新这个字段。如果用户在过去半小时内一直处于活动状态,您可以说他已登录。或类似的东西。【参考方案12】:

最好将 login=true 存储在会话变量中以检查用户是否登录。这将解决您的大部分问题;)

【讨论】:

以上是关于如何在php中检测用户是不是已注销?的主要内容,如果未能解决你的问题,请参考以下文章

根据用户是不是已登录切换登录/注销

当用户尝试再次输入用户名时,如何删除“您已注销”

您如何在 spring-security 中注销所有已登录的用户?

自动检测浏览器选项卡中的注销?

如何让 .NET Windows 服务检测登录、注销和切换用户事件?

如果用户从 IdentityServer4 中的另一个浏览器/设备登录,如何检测并从应用程序中注销用户?