JS/php 每分钟添加一次

4
我希望每个用户每分钟都能获得1个点数。现在我有一个addpoints.php的php代码,我尝试使用jQuery javascript进行操作:
function addpoints()  { 
  var userid = document.getElementById('user_id_points');
  var postFile = 'addpoints.php?userid='+ userid.value;
  $.post(postFile, function(data){  
    $("#points").html(data); 
    setTimeout(addpoints, 60000);
  });
}    

这个方法很有效,每1分钟会获得一个点数。但是有一个问题,如果你只是刷新了脚本所在的页面,你也会获得一个点数。因此,你可以多次刷新页面来提高你的点数。
我想,可以在addpoints.php中添加一个if()语句,检查上一次时间戳是否超过1分钟,如果是则发放点数,否则报错。
我只是想知道是否有更好的方法来解决这个小问题?
4个回答

3

将最后一次增加分数的日期+时间(例如使用时间戳)存储在该分数旁边(无论是在$_SESSION还是数据库中)确实是一个解决方案:

  • 当收到增加分数的请求时,请检查时间戳
    • 如果距现在已经超过60秒,则增加分数并更新时间戳
    • 否则,不要更新分数或时间戳

不经常访问数据库的方法(即在不需要更新分数的情况下,因为时间少于1分钟)可能是将时间戳存储在会话中(请参阅http://www.php.net/manual/en/book.session.php);;但清除浏览器中的cookie或使用另一个浏览器或自动化脚本就足以更改会话--这意味着它不像将时间戳存储在数据库中那样安全(实际上,我会将时间戳存储在数据库中,旁边是分数)。 - Pascal MARTIN
好的,谢谢。我应该如何编写if语句呢?如果($row["lastpoint"] + 60 == time()) { //插入到数据库 } else { //不插入 } 这样正确吗? - Karem
我至少会使用诸如 <> 这样的比较,而不是 == :如果查询在61秒后到达,则应考虑;我可能会将条件放在 update 查询中;伪代码:update your_table set points = points+1, timestamp=$current_time where user_id=X and timestamp<=$current_time-60 ;否则,从您提议的内容开始,我认为这可能没问题:if ($row['last_time'] + 60 <= time()) {insert} - Pascal MARTIN
我认为你首先要使用mysql_query运行实际查询,然后调用mysql_affected_rows,不需要传递任何参数: 它将在最后一个运行的查询上工作 - 请参阅mysql_affected_rows手册页面上的示例:其中有一个是带有update查询的。 - Pascal MARTIN
我按照您说的做了,但是我收到了一个错误警告:mysql_num_rows()的参数数量不正确。代码如下所示: mysql_query("UPDATE member_profile set points = points+1, lastpoint=$tid WHERE lastpoint<=$tid-60 AND user_id = '".$userid."'"); 如果 (mysql_num_rows() == 1) { 没有任何参数,但仍然出现错误。 - Karem
显示剩余5条评论

0

你应该只在 $_SESSIONS 中存储时间戳,不必担心数据库中的内容。为了防止自动化脚本,你可以做的另一件好事是启用某种身份验证来访问页面,最好使用登录和强大的验证码。还要确保防范表单欺骗并存储同一 IP 的多个请求并禁止它们。这将防止有人通过多次刷新 DOS 攻击你的服务器。你可以使用其他方法来确定是否正在进行自动化操作,例如 IP、引荐检查等。


0

根据 @Pascal MARTIN 的回复,如果解决方案可行,您可以选择 @Pascal MARTIN 的回复

function addpoints()  { 
  var userid = document.getElementById('user_id_points');
  var postFile = 'addpoints.php?userid='+ userid.value;
  $.post(postFile, function(data){  

    $("#points").html(data.html); 
    setTimeout(addpoints, data.ts);
  });

}   

只获取“addpoints_get_ts”中的时间戳

(function(){
  var userid = document.getElementById('user_id_points');
  var postFile = 'addpoints_get_ts.php?userid='+ userid.value;
  $.get(postFile, function(data){  
      setTimeout(addpoints, data.ts);
  });
})();

0
我建议在你的MYSQL表中添加一个名为last的列。这样,你就可以确保他们不会作弊。
mysql_query('UPDATE `users` SET `points` = `points`+1, `last`='.time().' WHERE `last` < '.(time()-60).' AND `user_id` = '.intval($_GET['userid']).' LIMIT 1);

此外,你可以使用SESSION变量来确保正确的用户调用脚本,或者甚至确保用户已经登录。;)


哎呀!这正是Pascal MARTIN所说的。 - Daan
它只是将 .time() 插入到数据库中,这不正确吗? - Karem
这是为了保存之前的时间,以便您知道他们是否尝试作弊。它还会增加积分(仅在自上次增加以来已经过去60秒时才增加)。 简而言之,这就是您告诉MYSQL的内容:(仅当自上次时间以来已经过去60秒时)将“points”增加1并更新时间戳。 - Daan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接