当用户关闭浏览器或自动会话销毁时,PHP SESSION会破坏

时间:2015-01-12 20:11:24

标签: php session cron onbeforeunload


我的登录注销脚本中有一个漏洞,我真的不知道如何填写它。 当用户开始简单地离开页面而不是退出时,整个问题就出现了。实际上它不会有任何不好之处,因为在我的代码中有15分钟后退出(会话超时),但在我的数据库中有一个列" online"在登录和注销时更改,因此当用户关闭页面时,它不会更改为脱机。

我正在尝试window.onbeforeunload来href到注销所在的页面(没有工作) 我也听说过cron,但我完全不知道如何做到这一点。

任何人都可以通过详细解释告诉我如何解决我的问题吗? 期待您的回音。

1 个答案:

答案 0 :(得分:1)

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

我想我已经解释得非常糟糕。

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

因此,每次加载页面或每次处理ajax调用时,都会更新timstamp字段,然后更新时间戳大于X分钟的任何字段,这是因为他们(可能)注销,因此它们在DB中被更改为" offline"。虽然如果他们只是忙着但仍然在线,也许实际上并未将其注销,只需将其标记为离线即可。

我没有详细说明如何处理您的数据库内容详细信息等,所以我的想法可能与您可以创建的内容完全不同 - ?

编辑: Ajax建议

要让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> 

AJAX PAGE: 请注意,在这种情况下,更新时间是一个&#39;时间戳&#39; 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();

}

这应该保持时间戳值最新,所以登录的人是UpdateTime超过time() - 601(10:01分钟)的任何人,SQL列表可以在任何人发生的任何标题/类上更改此访问任何页面

SQL = "UPDATE Members SET LoggedIn = 'NO' WHERE UpdateTime < (NOW() - INTERVAL 10 MINUTE)"