用户关闭浏览器时PHP会话销毁或自动会话销毁

用户关闭浏览器时PHP会话销毁或自动会话销毁,php,session,cron,onbeforeunload,Php,Session,Cron,Onbeforeunload,我的登录注销脚本有一个漏洞,我真的不知道如何填补它。 当用户开始简单地离开页面而不是注销时,整个问题就出现了。实际上,这并没有什么不好的,因为在我的代码中,15分钟后(会话超时)会注销,但在我的数据库中,有一列“online”在登录和注销时会更改,所以当用户刚刚关闭页面时,它不会更改为offline 我正在尝试window.onbeforeunload将href卸载到注销所在的页面(不起作用) 我也听说过cron,但我完全不知道如何做到这一点 有人能详细解释一下如何解决我的问题吗? 期待您的来信


我的登录注销脚本有一个漏洞,我真的不知道如何填补它。 当用户开始简单地离开页面而不是注销时,整个问题就出现了。实际上,这并没有什么不好的,因为在我的代码中,15分钟后(会话超时)会注销,但在我的数据库中,有一列“online”在登录和注销时会更改,所以当用户刚刚关闭页面时,它不会更改为offline

我正在尝试window.onbeforeunload将href卸载到注销所在的页面(不起作用) 我也听说过cron,但我完全不知道如何做到这一点

有人能详细解释一下如何解决我的问题吗?

期待您的来信

一个解决方案是,每次加载页面时,或者可能是每个页面的ajax请求,将代码反弹到服务器上,说“嘿,这个用户在线了”,然后在脚本中内置一个函数(可以在任何页面上工作,任何人都可以查看)检查mysql更新时间是否在最后X分钟内,如果不是,则假定用户已注销

我想我解释得很糟糕

您的表中有一个时间戳字段-与每个登录的用户关联,如果时间戳上次更新在现在的X分钟内,则他们被视为在线

因此,每次加载页面或处理ajax调用时,timstamp字段都会更新,然后在时间戳早于X分钟的任何字段上,这是因为它们(可能)已注销,因此在DB中会更改为“脱机”。虽然如果他们很忙,但仍然在线,也许不会真正将他们注销,只是将他们标记为离线

我运行时没有关于如何处理数据库内容详细信息等的详细信息,因此我的想法可能与您可以创建的内容完全不同-

编辑: 阿贾克斯建议

为了让ajax每X秒在每个页面上运行一次,请在成员所在的页面上写入以下ajax,注意末尾的数字是毫秒,600000=10分钟。所以使用了500000,因为它在时间范围内。因此ajax函数每8.5分钟运行一次,或者在页面加载时运行一次

ajax编写得相当糟糕,可能还可以改进。但应该有效。您需要研究一个更优化的ajax脚本

浏览器页面:

<script src="js/jquery-1.11.1.min.js" type="text/javascript" ></script>
 <script type="text/javascript">

     $( document ).ready(function() {
    var memberId = <?php print $memberId; ?>;
var securityKey = <?php print some security key code or suchlike to validate this ajax at the otherend;?>;

         setInterval(function(){
         $.post("/ajaxSession.php",{
                MemberId: memberId,
                somesecuritykey: securityKey
            });
        }, 500000);
    });

</script> 

$(文档).ready(函数(){
var memberId=;
var securityKey=;
setInterval(函数(){
$.post(“/ajaxSession.php”{
MemberId:MemberId,
somesecuritykey:securityKey
});
}, 500000);
});
AJAX页面: 请注意,本例中的更新时间是一个“timestamp”MySQL字段

    <?php
    /**
    Setup this page as if any other PHP page but this page will never show to the browser,
    AJAX data is supplied as $_POST and inn this case $_POST['somesecuritykey'] and $_POST['MemberId'] 
    **/

session_start();
/**
include classes and files
**/
if (is_numeric($_POST['MemberId'])){
$memid= (int)$_POST['MemberId'];

/**Also include your security stuff here **/

$sql = "UPDATE Members SET UpdateTime = NOW() , LoggedIn = 'YES' WHERE MemberId = ? LIMIT 1"
$mysqli = new mysqli();
$mysqli->prepare($sql);
$mysqli->bind_param("i",$memid);
$mysqli->execute();

}

不可能。您无法可靠地检测某人何时关闭窗口或选项卡。。。如果一个用户在你的站点上打开了多个选项卡,并关闭了一个选项卡,你将如何检测?现在他们在所有标签上都注销了。PHP本身无论如何都会清除过时的会话。你不需要做任何事情,只需要设置会话的生命周期-让PHP来处理它。我想看到在线的人,我的数据库中有它,我应该怎么做呢?将“现在谁在线”改为“过去15分钟内谁做了什么”。同意Marc B。您可以潜在地分析您用户的最后活动日期,然后对该信息进行投票。如果人们在过去五分钟左右没有做任何事情,那么添加一个“空闲”状态或其他东西。如果他们在会话过期所需的时间内没有做任何事情,则更新UI以显示他们脱机。所有内容都保存在数据库中,所以我可能会在db中设置一些类似预期注销时间的内容,并每15分钟运行此脚本?(和克朗)好的,我想我有个主意。我将每隔15分钟运行一次脚本,以检查用户上次活动是否在15分钟内。我使用的是php和mysql,所以有一个名为LoginTimestamp的专栏,然后每隔10分钟左右运行一次ajax,最大时间保持在15分钟之内,看看他们是否在线,然后更新时间戳,如果他们的时间戳SQL = "UPDATE Members SET LoggedIn = 'NO' WHERE UpdateTime < (NOW() - INTERVAL 10 MINUTE)"