You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修复PHP MySQL jQuery Ajax实现Feed流点赞时全帖点赞数同步错误问题

类Facebook新闻Feed点赞计数异常修复方案

问题根因

  • 前端Ajax成功回调使用全局选择器$(".ajax_like_result"),会匹配页面内所有带该class的点赞数展示节点,导致单次点赞操作会覆盖所有帖子的计数
  • 直接将class替换为id的方案不符合HTML id全局唯一的规范,且未在点击事件中关联当前点击按钮对应的计数节点,因此仅第一条帖子功能正常,其余帖子无响应
  • 后端代码存在3个明显问题:直接拼接前端参数到SQL语句存在SQL注入风险、先查询再更新的逻辑在高并发下会出现计数偏差、声明返回json格式但实际直接输出数字会触发前端解析报错,还遗留了无意义的enter code here冗余字符

分步修复代码

1. 前端交互逻辑修复

点击事件触发时先缓存当前点击的按钮节点,回调时仅操作该节点内部的点赞数展示元素,不做全局匹配;同时修正返回数据类型避免解析错误。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> 
<script type="text/javascript">
$(document).ready(function(){        
    $('.ajax_like').on('click', function () {
        // 缓存当前点击的帖子点赞按钮节点,后续操作仅针对当前帖子
        const currentPostItem = $(this);
        var post_id = currentPostItem.val(); 
        var page = currentPostItem.attr("data-id"); 
        
        $.ajax({
            type: 'POST',
            url: 'like.php',
            data: {post_id:post_id, page:page},
            dataType: 'text', // 后端直接返回数字,使用text类型避免json解析报错
            success: function(data){                
                // 仅更新当前帖子下的点赞计数节点,不影响其他帖子
                currentPostItem.find(".ajax_like_result").html(data);              
            }
        });
    });
});
</script>

2. HTML模板调整

不需要把class属性替换为id,保持原有class写法即可,因为已经通过节点父子关系锁定了当前帖子的计数元素,原有模板代码可正常使用:

<li class="ajax_like" type="submit" name="data-id" data-id="<?php echo $page;?>" value="<? echo $post_id;?>">                         
    <div class="ajax_like_result"><?php print $likes;?></div>
</li>

3. 后端接口like.php修复

  • 使用预处理语句绑定参数,新增表名白名单校验,封堵SQL注入漏洞
  • 去掉先查再改的冗余逻辑,直接用SQL内置的自增语法更新计数,避免并发下计数不准
  • 增加基础参数校验、登录态校验,删除冗余遗留代码
<?php 
session_start();
$conn=mysqli_connect("localhost", "u1068033_ab24", "ab@24", "u1068033_ab24");
mysqli_set_charset($conn,"utf8");

// 未登录状态直接终止请求
if(empty($_SESSION['id'])){
    exit("0");
}
$id = $_SESSION['id'];

// 参数格式校验
$get_post_id = intval($_POST['post_id']);
// 配置允许访问的表名白名单,替换为你业务中实际用到的表名即可,禁止直接拼接前端传入的表名
$allowed_pages = ['posts', 'user_wall_posts'];
$page = $_POST['page'];
if(!in_array($page, $allowed_pages) || $get_post_id <= 0){
    exit("参数非法");
}

// 直接执行自增操作,不需要提前查询当前点赞数,避免并发计数偏差
$update_stmt = mysqli_prepare($conn, "UPDATE `$page` SET `likes` = `likes` + 1 WHERE `post_id` = ?");
mysqli_stmt_bind_param($update_stmt, "i", $get_post_id);
mysqli_stmt_execute($update_stmt);

// 查询更新后的点赞数返回前端
$query_stmt = mysqli_prepare($conn, "SELECT `likes` FROM `$page` WHERE `post_id` = ?");
mysqli_stmt_bind_param($query_stmt, "i", $get_post_id);
mysqli_stmt_execute($query_stmt);
$result = mysqli_stmt_get_result($query_stmt);
$row = mysqli_fetch_assoc($result);
echo $row['likes'];
?>

可选优化项

  • 增加点赞防抖逻辑,避免用户快速连续点击按钮触发重复请求
  • 新增用户点赞关联表,校验用户是否已对当前帖子点赞,防止同一用户重复刷赞
  • 取消前端传表名的逻辑,通过帖子类型枚举在后端做映射,进一步降低安全风险

内容的提问来源于stack exchange,提问作者mhbd2009

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 07:48:57