如标题所述,db表 trace_users
没有得到更新 30分钟无活动时 但它的更新时间是6分钟。
以下代码 (包括JS和PHP) 在同一个php文件中 mno.php.
我通过这一行来存储用户的最后一次活动。let lastActivity = <?php echo time(); ?> ;
存在于下面的脚本中。
<?php
session_start();
if (isset($_GET['action']) && $_GET['action'] == "logout")
{
session_destroy(); // destroy session data in storage
!isset($_SESSION['pageadmin']);
$open = "false";
$write = "0";
$stmt = $connect->prepare("UPDATE trace_users SET open=?, write=? WHERE user_name=?");
$usname = !empty($_SESSION['user_name']) ? $_SESSION['user_name'] : '';
$stmt->bind_param('sss', $open, $write, $usname);
$stmt->execute();
}
?>
<script>
jQuery(document).ready(function($) {
let lastActivity = <?php echo time(); ?> ; // storing last activity of user
let now = <?php echo time(); ?> ;
let logoutAfter = 360;
let timer = setInterval(function() {
now++;
let delta = now - lastActivity;
console.log(delta);
if (delta > logoutAfter) {
clearInterval(timer);
//DO AJAX REQUEST TO close.php
$.ajax({
url: "/abc/mno.php",
type: 'GET',
data: {
action: 'logout'
}, // Line A
success: function(data) {
console.log(data); // Line B
},
error: function(jqXHR, textStatus, errorThrown) {
alert(textStatus);
}
});
}
}, 1000);
});
</script>
问题陈述。
我想知道我应该在上面的代码中做哪些修改,以使 当30分钟(1800秒)内没有活动发生时,db表也应该得到更新。.
案例1(不工作) : 1800秒 (页面登出。数据库不更新) 案例2(工作) : 360秒 (页面登出。数据库得到更新)
session.gc_maxlifetime里面的值是1440(本地值) 1440(主值)
这是我试过的debugged。
在 "网络 "选项卡上,我得到的是 "请求方法"。获取 当设置了会话超时时 6分钟 和 60分钟.
你需要给javascript传递一些永久的UID来识别用户。即使会期过后.
为简化起见,我使用的是 user_name
,已经存在于你的代码中。但你也可以为每个用户分配一个UUID,这样就不能猜测另一个用户的名字,也不能修改他们的统计数据。
首先,你将通过 $_SESSION['user_name']
从PHP到JS封闭。
let userName = "<?php echo $_SESSION['user_name']; ?>"; // don't forget to wrap the JS string value in quotes or apostrophes
然后,你将在AJAX请求的有效载荷中传递它。
data: {
action: 'logout',
user_name: userName // added param
},
最后,你将覆盖被发送到DB的值(如果它是和有效载荷一起发送的话
$usname = !empty($_SESSION['user_name']) ? $_SESSION['user_name'] : ''; // original line
if (isset($_GET['user_name']) && !empty($_GET['user_name'])) {
$usname = $_GET['user_name'];
}
$stmt->bind_param('sss', $open, $write, $usname); // original line
完整的更新代码。
<?php
if (isset($_GET['action']) && $_GET['action'] == "logout")
{
session_destroy(); // destroy session data in storage
!isset($_SESSION['pageadmin']);
$open = "false";
$write = "0";
$stmt = $connect->prepare("UPDATE trace_users SET open=?, write=? WHERE user_name=?");
$usname = !empty($_SESSION['user_name']) ? $_SESSION['user_name'] : '';
if (isset($_GET['user_name']) && !empty($_GET['user_name'])) {
$usname = $_GET['user_name'];
}
$stmt->bind_param('sss', $open, $write, $usname);
$stmt->execute();
}
?>
<script>
jQuery(document).ready(function($) {
let lastActivity = <?php echo time(); ?> ; // storing last activity of user
let now = <?php echo time(); ?> ;
let logoutAfter = 10;
let userName = "<?php echo $_SESSION['user_name']; ?>";
let timer = setInterval(function() {
now++;
let delta = now - lastActivity;
console.log(delta);
if (delta > logoutAfter) {
clearInterval(timer);
//DO AJAX REQUEST TO close.php
$.ajax({
url: "/abc/mno.php",
type: 'GET',
data: {
action: 'logout',
user_name: userName
}, // Line A
success: function(data) {
console.log(data); // Line B
},
error: function(jqXHR, textStatus, errorThrown) {
alert(textStatus);
}
});
}
}, 1000);
});
</script>
最后的一些说明。
<script src="...jquery.js">
,有一个DB查询,但没有单独的SQL导入,可以快速尝试)。) 请大家阅读并运用所学知识,从 如何创建一个最小的、可复制的例子。 在你的下一个问题中,让更多的人能够或愿意帮助你解决这个问题。问题是你并没有改变任何东西来防止会话在N秒后过期,你只是将你的脚本编码成在这个时间后会销毁会话的方式。会话gc(garbage colector)会定期执行,并删除旧的会话,当发生这种情况时。$_SESSION['LAST_ACTIVITY']
也会被删除。
你必须设法阻止gc删除会话,或者改变你的应用程序的逻辑。
PHP进程不会无限期地坐着,也没有像Node.js服务器那样的循环程序结构,这就不允许你对session过期做出反应,因为它不是一个使其失效的进程,而是一个与session相关联的简单的时间戳,每次你试图使用它时都会检查。
我提供的解决方案是一个简单的脚本,每隔N分钟运行一次,将最后一个用户活动的时间戳(我认为这个时间戳是在该用户的请求中更新的)与到期时间(在你的情况下是30分钟)进行比较。你也可以将会话到期时间设置为30分钟,不过严格来说这不是必要的。如果时间差超过30分钟,你就更新表中用户的时间戳,如果必要的话,还可以使他们的会话无效。脚本可以通过cron或其替代品运行,并通过所有你需要执行检查的用户。
有两件事你需要解决。
1). 将ajax请求设置为 async:false
.
$.ajax({
url: "/abc/mno.php",
type: 'GET',
async: false, // <---- ADDED ASYNC FALSE
data: {
action: 'logout'
}, // Line A
success: function(data) {
console.log(data); // Line B
},
error: function(jqXHR, textStatus, errorThrown) {
alert(textStatus);
}
});
2). 执行SQL查询后销毁会话。
<?php
session_start();
if (isset($_GET['action']) && $_GET['action'] == "logout")
{
!isset($_SESSION['pageadmin']);
$open = "false";
$write = "0";
$stmt = $connect->prepare("UPDATE trace_users SET open=?, write=? WHERE user_name=?");
$usname = !empty($_SESSION['user_name']) ? $_SESSION['user_name'] : '';
$stmt->bind_param('sss', $open, $write, $usname);
$stmt->execute();
session_destroy(); // destroy session data in storage <---- DESTORY AT THE END
}
?>