Javascript 在php中更新会话超时的数据库表

Javascript 在php中更新会话超时的数据库表,javascript,php,sql,ajax,session-timeout,Javascript,Php,Sql,Ajax,Session Timeout,我有一个php代码,如下所示,其中会话超时发生在没有活动的60分钟之后。以下代码位于文件/mno.php中。我的登录和注销code也在同一个文件/mno.php中 /mno.php if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 3600)) { session_destroy(); // destroy session data in storage

我有一个php代码,如下所示,其中会话超时发生在没有活动的60分钟之后。以下代码位于文件/mno.php中。我的登录和注销code也在同一个文件/mno.php

/mno.php

if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 3600)) {
    session_destroy();   // destroy session data in storage
    !isset($_SESSION['pageadmin']);

    /* Update Table (START) */
    $open="false";
    $stmt= $connect->prepare("UPDATE trace_users SET open=? WHERE user_name=?");
    $stmt->bind_param('ss', $open, $_SESSION['user_name']);
    $stmt->execute();
    /* Update Table (END) */

    header('location: /mmo.php');
    exit();
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp 
代码中的表trace_users记录所有登录用户。在该表中,有两列用户名打开。当任何用户登录/注销时,该值设置为true/false

我已经包含了sql查询,在该查询中,我试图在没有活动时更新一个表,但不幸的是,当60分钟内没有活动发生时,该特定用户的列值没有设置为false

这就是我尝试过的:

在做了一些研究之后,我想我必须运行一个计时器(js/ajax)。在下面显示的javascript中,我计算了最后一个活动当前时间之间的差异。 如果超过60分钟,则会更新db表。这是我尝试过的,但我相信为了更新数据库中的表,还需要做更多的工作

<script>
let x = setInterval(function() {

    let lastActivity = <?php echo ($_SESSION['LAST_ACTIVITY']); ?>
    let now = <?php echo time() ?>;
    let difference = now - lastActivity;

    if (difference > 3600) {
        clearInterval(x);
    }
}, 1000
);
</script>   

设x=setInterval(函数(){
让lastActivity=
现在让我们=;
让差异=现在-上次活动;
如果(差异>3600){
净间隔(x);
}
}, 1000
);
问题陈述:

我想知道我应该在上面的js(或php)代码中做什么更改,以便在60分钟内没有活动时,它应该将该特定用户的列open更新为false(在表trace_users中)

编辑1:


我的登录代码和会话历史记录代码在同一个文件/mno.php中。我将所有内容都放在同一个文件中/mno.php

这是一个简单的网页时间验证:

$modified_on = isset($SERVER['HTTP_IF_MODIFIED_SINCE']) ? $SERVER['HTTP_IF_MODIFIED_SINCE'] : null;

$current_time = time();

if (!is_null($modified_on) && ($current_time - strtotime($modified_on)) > 3600) {
    session_destroy();
    ...
}

header('Last-Modified: '.gmdate('D, d M Y H:i:s', $current_time).' GMT');

...

我想你已经意识到这个密码

if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 3600)) {
    //...
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp 
在每个请求上运行,仅当请求到达时运行

想象一下,我访问你的网站,然后出去购物,保持浏览器打开。你认为会发生什么? 没有-因为不会向您发送新请求(假设您没有实现任何定期ajax轮询/Websocket机制)

因此,在我购物回来并刷新页面之前,服务器不会为我操心,只有到那时服务器才会意识到“嗯……这家伙的最后一次_活动已经超过一个小时了。让我更新我的
跟踪_用户
表,并为他设置为打开

对于您提出的解决方案,它看起来不错,并且避免了WebSocket/定期ajax请求的复杂性

只需要一些小的修改,下面是一个基本的演示

<script>

    var lastActivity = <?php echo ($_SESSION['LAST_ACTIVITY']); ?>; //the timestamp of latest page refresh or navigation 
                                                                    //This will remain constant as long as page stays put
    var now = <?php echo time() ?>; //This takes inital value (technically same as LAST_ACTIVITY) from server 
                                    // but later on it will be incremented by javascript to act as counter
    var logoutAfter = 5; //I set 5 sec for demo purposes

    var timer = setInterval(function() {
                    now++;
                    let delta = now - lastActivity;
                    if ( delta > logoutAfter) {
                        alert('you are logged out');
                        clearInterval(timer);
                        //DO AJAX REQUEST TO close.php
                    }
                }, 1000);

</script> 

close.php


我认为Vineys和jo0gbe4bstjbs的答案是错误的,因为当用户关闭浏览器5秒钟后,它也无法在60分钟和会话后更新表。会话在php.ini配置文件中的where set中删除。
你介意每5秒请求一次吗?这是解决这个问题的好方法吗?这对性能是最差的。
如果您想通过专业化解决这个问题,您应该添加“last_request”列并从表中删除“open”列,并且在每个请求之后,您应该将last_requests值更新为当前unix时间戳。在获取用户时,您应该写:

$time = time() - 3600;

"SELECT * FROM `users` WHERE last_request > $time" //active users
"SELECT * FROM `users` WHERE last_request <= $time" //inactive users
$time=time()-3600;
“从'users'中选择*,其中上次请求>$time”//active users”
“从`users`WHERE last_requestPage.php中选择*

<!-- CODE TO INCLUDE IN HEADER.PHP -->

<?php  
session_start();
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp  
?>



<!-- CLOSE -->

<html>

<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
</head>

<body>

</body>

<script>
let lastActivity = <?php echo ($_SESSION['LAST_ACTIVITY']); ?>; //the timestamp of latest page refresh or navigation
//This will remain constant as long as page stays put
let now = <?php echo time() ?>; //This takes inital value (technically same as LAST_ACTIVITY) from server+
                                // but later on it will be incremented by javascript to act as counter
let logoutAfter = 5; //I set 5 secs for demo purposes


let timer = setInterval(function() {
    now++;
    let delta = now - lastActivity;

    if ( delta > logoutAfter) {
        alert('you are logged out');
        clearInterval(timer);
        //DO AJAX REQUEST TO close.php
        $.ajax({
            url: "/mmo.php",
            type: 'POST', // GET also fine
            data: { },
            success: function(data) {

            },
            error: function(jqXHR, textStatus, errorThrown) {
                console.log("I am inside error");
                alert(textStatus);
            }
        });
    }
}, 1000); //<-- you can increse it( till <= logoutAfter ) for better performance as suggested by @"Space Coding"

</script>

</html>

let lastActivity=;//最新页面刷新或导航的时间戳
//这将保持不变,只要页面保持不变
let now=;//这从服务器获取初始值(技术上与上一个_活动相同)+
//但稍后,它将通过javascript递增以充当计数器
让logoutAfter=5;//为了演示,我设置了5秒
let timer=setInterval(函数(){
现在++;
设delta=now-lastActivity;
if(delta>logoutAfter){
警报(“您已注销”);
清除间隔(计时器);
//是否执行关闭.php的AJAX请求
$.ajax({
url:“/mmo.php”,
键入:“POST',//也可以获得罚款
数据:{},
成功:功能(数据){
},
错误:函数(jqXHR、textStatus、errorshown){
log(“我是内部错误”);
警报(文本状态);
}
});
}
}, 1000); //

这是一个请求头,由浏览器发送。我检查了你的代码,看起来不错。谢谢你的帮助。我很高兴我的方法是正确的。谢谢你的确认。根据你提出的解决方案,当5秒钟内没有活动时,(1)页面应该自动注销,并让用户登录到login.php(在这里我将销毁会话)。(2)它还应该更新表。这是我尝试过的。我想知道您是否可以看一看。在小提琴中,您是否可以让我知道我需要在哪里调整更新查询以及下面正在销毁会话的两行。
session\u destroy();//销毁存储中的会话数据!isset($\u session['pageadmin']);
谢谢更新。我检查了你的代码,想让你知道一些事情。我的登录代码和会话历史记录代码在同一个文件/mmo.php中。我将所有内容都放在同一个php文件/mmo.php中。我尝试过使用此代码,但它不起作用。我收到了你注销并退出的警报消息error@user1950349代码沙盒是一个有限的环境,您需要在本地系统上进行测试。请使用php的effortles内置服务器
php-s localhost:8080
Hi,我共享了沙盒链接以显示我在本地系统中使用的代码。复制/粘贴
$time = time() - 3600;

"SELECT * FROM `users` WHERE last_request > $time" //active users
"SELECT * FROM `users` WHERE last_request <= $time" //inactive users
<!-- CODE TO INCLUDE IN HEADER.PHP -->

<?php  
session_start();
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp  
?>



<!-- CLOSE -->

<html>

<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
</head>

<body>

</body>

<script>
let lastActivity = <?php echo ($_SESSION['LAST_ACTIVITY']); ?>; //the timestamp of latest page refresh or navigation
//This will remain constant as long as page stays put
let now = <?php echo time() ?>; //This takes inital value (technically same as LAST_ACTIVITY) from server+
                                // but later on it will be incremented by javascript to act as counter
let logoutAfter = 5; //I set 5 secs for demo purposes


let timer = setInterval(function() {
    now++;
    let delta = now - lastActivity;

    if ( delta > logoutAfter) {
        alert('you are logged out');
        clearInterval(timer);
        //DO AJAX REQUEST TO close.php
        $.ajax({
            url: "/mmo.php",
            type: 'POST', // GET also fine
            data: { },
            success: function(data) {

            },
            error: function(jqXHR, textStatus, errorThrown) {
                console.log("I am inside error");
                alert(textStatus);
            }
        });
    }
}, 1000); //<-- you can increse it( till <= logoutAfter ) for better performance as suggested by @"Space Coding"

</script>

</html>
<?php

$servername = "localhost";
$username   = "username";
$password   = "password";
$dbname     = "myDB";

$connect = new mysqli($servername, $username, $password, $dbname);

if ($connect->connect_error) {
    die("Connection failed: " . $connect->connect_error);
}

session_start();
$logoutAfter = 5; //5 sec timeout for testing purposes

if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > $logoutAfter)) {
    session_destroy();   // destroy session data in storage
    !isset($_SESSION['pageadmin']);

    /* Update Table (START) */
    $open="false";

    $stmt= $connect->prepare("UPDATE trace_users SET open=? WHERE user_name=?");
    $usname = !empty($_SESSION['user_name'])?$_SESSION['user_name']:'';

    $stmt->bind_param('ss', $open, $usname );
    $stmt->execute();
    /* Update Table (END) */

    //header('location: /mmo.php'); //<-- no need of it when url hit by ajax
    exit();
}
else  //<-- note the else
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp  
?>