如何在PHP现有点赞逻辑中正确实现MySQL用户表点赞数自增更新操作
点赞数自增逻辑失效的核心原因
你之前写的更新语句不生效,本质是三个问题导致的:
- 用了已经被PHP彻底废弃的
mysql_query扩展
这套代码全局是用封装好的$db对象(Medoo类风格的数据库ORM)做数据库操作的,mysql_*系列函数从PHP 7.0版本开始就被完全移除,就算运行环境兼容老版本,这套函数维护的连接和项目自身的$db连接也是完全独立的,语句根本没法更新到项目对应的数据库实例上,自然看不到效果。 - 触发逻辑没有绑定点赞操作的实际成功结果
原来的更新语句没有判断操作是不是真的成功、是不是真的产生了“从未点赞到已点赞”的状态变更,不管是重复点击、操作报错、本来已经是点赞状态,只要进了流程就触发自增,最后不仅容易失效,还会把点赞总数算虚高。 - 没有处理状态切换的边界场景
比如用户之前给目标用户点过踩,现在切换成点赞,这时候才需要给对方的点赞数加1;但如果用户本来就已经是点赞状态,再触发请求,就不能重复加1。
正确的嵌入实现方案
调整后的完整逻辑核心是:
- 提前查询互动记录的原有状态,判断是否真的发生了“非点赞→已点赞”的有效变更
- 用项目现有的
$db连接执行自增更新,彻底废弃老的mysql_query写法 - 只有变更真实发生的时候,才触发被点赞用户的点赞数自增
$userid = Secure($_POST['username']); $user = $db->where('username', $userid)->getOne('users',array('id','web_device_id','is_pro')); // 查询当前登录用户给目标用户的已有互动记录,同时带出原有点赞状态 $exist_interact = $db->where('user_id', self::ActiveUser()->id) ->where('like_userid', $user['id']) ->getOne('likes', array('id', 'is_like')); $id = $exist_interact['id'] ?? 0; $saved = false; // 标记是否需要触发被点赞用户的总数自增 $need_increment = false; if ($id > 0) { $saved = $db->where('id', $id)->update('likes', array( 'user_id' => self::ActiveUser()->id, 'like_userid' => $user['id'], 'is_like' => 1, 'is_dislike' => 0, 'created_at' => date('Y-m-d H:i:s') )); // 只有更新成功、且原状态不是已点赞,才需要自增 if ($saved && $exist_interact['is_like'] != 1) { $need_increment = true; } } else { if(isUserLiked($user['id']) === false) { $saved = $db->insert('likes', array( 'user_id' => self::ActiveUser()->id, 'like_userid' => $user['id'], 'is_like' => 1, 'is_dislike' => 0, 'created_at' => date('Y-m-d H:i:s') )); // 新插入点赞记录成功,直接标记需要自增 if ($saved) { $need_increment = true; } } } // 满足真实点赞变更条件时,执行被点赞用户的点赞数自增 if ($need_increment) { // 用项目现有ORM的快捷自增写法,替代废弃的mysql_query $db->update('users', ['likes[+]' => 1], ['id' => $user['id']] ); // 如果当前ORM不支持字段快捷加减的写法,直接用ORM绑定的连接执行预编译SQL即可 // $db->query("UPDATE users SET likes = likes + 1 WHERE id = ?", [$user['id']]); }
额外优化注意点
- 原代码中
$is_user_matches变量查询后没有任何逻辑判断,属于冗余代码,可以直接删除减少不必要的数据库查询。 - 自增操作不要做无意义的多次执行:比如不要在插入、更新的每个分支里单独写一次自增,统一在流程末尾根据标记判断执行,减少代码重复。
- 预编译参数绑定要做好,不要直接拼
$user['id']进SQL字符串,避免注入风险。
内容的提问来源于stack exchange,提问作者Onica Cosmin
相关产品推荐
相关产品推荐

