обновить таблицу базы данных по времени ожидания сеанса в php - PullRequest
2 голосов
/ 19 апреля 2020

У меня есть код php, как показано ниже, в котором тайм-аут сеанса происходит через 60 минут, когда нет активности. Следующий код находится внутри файла / mno. php. Мой код входа и выхода e также находится в том же файле / 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 в коде отслеживает всех зарегистрированных пользователей. В этой таблице есть два столбца user_name и open . Значение установлено на true / false , когда любой пользователь входит / выходит .

Я включил sql запрос, в который я пытаюсь обновить таблица, когда нет активности, но, к сожалению, значение столбца не устанавливается в false для этого конкретного пользователя , когда в течение 60 минут не происходит никаких действий.

Вот что я попробовал:

После некоторых исследований я думаю, что мне нужно запустить таймер (js / ajax). В показанном ниже javascript я вычислил разницу между последней активностью и текущим временем . Если его больше 60 минут, он обновит таблицу БД. Это то, что я пытался, но я считаю, что нужно сделать больше, чтобы обновить таблицу в БД.

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

Постановка проблемы:

Мне интересно, какие изменения я должен внести в код js (или php) выше, чтобы при появлении без активности в течение 60 минут следует обновить столбец open до false (в таблице trace_users ) для этого конкретного пользователя.

enter image description here

Редактировать 1:

Мой код входа и код истории сеанса находятся в одном файле / MnO. php. Я поместил все в один файл / mno. php.

Ответы [ 4 ]

2 голосов
/ 20 апреля 2020

Я думаю, что ответ Vineys и jo0gbe4bstjbs неверен, потому что, когда пользователь закрывает браузер до 5 секунд, он не может обновить таблицу через 60 минут и сеанс тоже. Сеанс удаляется сразу после времени, указанного в файле конфигурации php .ini. И не возражаете ли вы запрашивать каждые 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

И вместо ajax запроса каждые 5 секунд вы должны написать setTimeout с задержкой 3600 секунд, которая запускает window.location.href = '/mmo.php '; код. Это хорошо, если вам нужна лучшая производительность и точный результат с 60-минутным выходом из системы

1 голос
/ 19 апреля 2020

Полагаю, вы понимаете, что этот код

if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 3600)) {
    //...
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp 

запускается при каждом запросе и только при поступлении запроса

Представьте, что я захожу на ваш сайт, а затем go за покупками, сохраняя браузер открытым. Как ты думаешь, что произойдет? НИЧЕГО - потому что вам не будет отправлен новый запрос (при условии, что вы не внедрили механизм periodi c ajax опроса / Websocket)

Так что сервер не будет беспокоиться обо мне, пока я не приду Вернитесь из магазина и обновите страницу sh, только тогда сервер поймет: «Хммм ... LAST_ACTIVITY этого парня старше часа, позвольте мне обновить таблицу trace_users и установить для него значение false"

Что касается предложенного вами решения, оно выглядит хорошо и позволяет избежать сложностей websockets / periodi c ajax запросов

Просто нужно внести некоторые незначительные исправления, следуйте здесь для ознакомления с c demo

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

Здесь lastActivity будет содержать метку времени, когда страница была отправлена ​​сервером в браузер, она никогда не будет изменяться скриптами в браузере, now - ваш счетчик, который вы будете использовать для отслеживания того, сколько время, прошедшее с момента загрузки страницы в браузер, вы будете увеличивать ее каждую секунду и проверять, не прошло ли заданное количество времени

Если true, выполните * 10 46 * запрос (или просто перенаправление на выход из системы. php), где вы бы уничтожили сеанс и обновили таблицу trace_users, чтобы пометить пользователя как закрытого

ОБНОВЛЕНИЕ

Так ajax будет похоже на

$.ajax({      
    url: "/close.php", 
    type: 'POST', // GET also fine
    data: { },
    success: function(data) {
        window.location.href= '/mmo.php';
    },
    error: function(jqXHR, textStatus, errorThrown) {
        alert(textStatus);
    }
}); 

и

close. php

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

// I'm not sure whether the below if condition check is required here or not 
// because we have already checked (whether to timeout or not ) in our javascript 
// and we call close.php only when it's affirmative
// I encourage you to test and find out :)

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=?");
    $stmt->bind_param('ss', $open, $_SESSION['user_name']);
    $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 
0 голосов
/ 21 апреля 2020

Стр. 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>

ммм. php

<?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  
?>
0 голосов
/ 19 апреля 2020

Это простая проверка времени для веб-страницы:

$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');

...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...