PHP/AJAX点赞按钮开发求助:PHP端单次点赞功能实现
实现绑定用户的单帖唯一点赞功能(PHP后端)
没问题,我来帮你搞定这个点赞功能的PHP后端实现,核心就是把用户ID和帖子ID绑定起来,从数据库层面和业务逻辑层面双重防止重复点赞。下面一步步来:
1. 先确认数据库结构
你需要两个表(或者在现有表基础上新增字段/表):
- 帖子表(比如命名为
posts):需要至少包含id(帖子唯一ID)、like_count(点赞计数,初始值设为0)字段。 - 点赞记录表(比如命名为
post_likes):用来存用户的点赞记录,字段包括id(自增主键)、user_id(登录用户的ID)、post_id(被点赞的帖子ID)。记得给user_id和post_id设置联合唯一索引,这样数据库层面直接阻止同一用户重复点赞同个帖子,避免脏数据。
2. 编写ajax/post_like.php的后端逻辑
这个文件是AJAX请求的处理核心,代码如下(带详细注释):
<?php // 启动会话,用来获取当前登录用户的ID session_start(); // 先判断用户是否登录,如果没登录直接返回错误 if (!isset($_SESSION['user_id'])) { echo json_encode([ 'status' => 'error', 'msg' => '请先登录再点赞' ]); exit; } // 获取AJAX传过来的帖子ID $post_id = isset($_POST['id']) ? intval($_POST['id']) : 0; if ($post_id <= 0) { echo json_encode([ 'status' => 'error', 'msg' => '无效的帖子ID' ]); exit; } // 连接数据库(这里换成你的数据库配置) $conn = mysqli_connect('localhost', '你的用户名', '你的密码', '你的数据库名'); if (!$conn) { die('数据库连接失败: ' . mysqli_connect_error()); } mysqli_set_charset($conn, 'utf8mb4'); $user_id = $_SESSION['user_id']; // 第一步:检查当前用户是否已经给这个帖子点过赞 $check_sql = "SELECT id FROM post_likes WHERE user_id = ? AND post_id = ?"; $stmt = mysqli_prepare($conn, $check_sql); mysqli_stmt_bind_param($stmt, 'ii', $user_id, $post_id); mysqli_stmt_execute($stmt); mysqli_stmt_store_result($stmt); if (mysqli_stmt_num_rows($stmt) > 0) { // 已经点过赞了,返回提示 echo json_encode([ 'status' => 'error', 'msg' => '你已经给这个帖子点过赞啦' ]); mysqli_stmt_close($stmt); mysqli_close($conn); exit; } // 第二步:如果没点过赞,执行点赞操作 // 先插入点赞记录 $insert_like_sql = "INSERT INTO post_likes (user_id, post_id) VALUES (?, ?)"; $stmt = mysqli_prepare($conn, $insert_like_sql); mysqli_stmt_bind_param($stmt, 'ii', $user_id, $post_id); $insert_success = mysqli_stmt_execute($stmt); // 再更新帖子的点赞计数 $update_count_sql = "UPDATE posts SET like_count = like_count + 1 WHERE id = ?"; $stmt = mysqli_prepare($conn, $update_count_sql); mysqli_stmt_bind_param($stmt, 'i', $post_id); $update_success = mysqli_stmt_execute($stmt); if ($insert_success && $update_success) { // 获取更新后的点赞数,返回给前端 $get_count_sql = "SELECT like_count FROM posts WHERE id = ?"; $stmt = mysqli_prepare($conn, $get_count_sql); mysqli_stmt_bind_param($stmt, 'i', $post_id); mysqli_stmt_execute($stmt); mysqli_stmt_bind_result($stmt, $like_count); mysqli_stmt_fetch($stmt); echo json_encode([ 'status' => 'success', 'msg' => '点赞成功', 'like_count' => $like_count ]); } else { echo json_encode([ 'status' => 'error', 'msg' => '点赞失败,请稍后重试' ]); } // 清理资源 mysqli_stmt_close($stmt); mysqli_close($conn); ?>
3. 完善前端AJAX逻辑(补充你没写完的部分)
为了提升用户体验,点击后要禁用按钮防止重复提交,还要根据后端返回更新页面显示:
$('a.like').on('click', function (e) { e.preventDefault(); // 阻止a标签默认跳转 var $this = $(this); var post_id = $this.attr('id'); // 点击后禁用按钮,防止重复提交 $this.prop('disabled', true).text('点赞中...'); $.ajax({ url: "ajax/post_like.php", method: "POST", data: { id: post_id }, dataType: 'json', success: function (response) { if (response.status === 'success') { // 更新点赞数显示,比如把按钮文本改成点赞数 $this.text('已点赞 (' + response.like_count + ')'); // 可以给按钮加个样式标记已点赞 $this.addClass('liked'); } else { alert(response.msg); // 恢复按钮状态 $this.prop('disabled', false).text('like'); } }, error: function () { alert('网络出错,请稍后重试'); $this.prop('disabled', false).text('like'); } }); });
4. 额外注意事项
- 一定要用预处理语句(prepared statements),防止SQL注入,上面的代码已经用了,别直接拼接SQL!
- 确保你的登录逻辑已经把用户ID存在
$_SESSION['user_id']里,不然后端没法识别当前用户。 - 页面加载的时候,可以先查询用户是否已经给该帖子点过赞,提前把按钮设置为“已点赞”状态,避免用户看到可点击的按钮但实际不能点赞。
内容的提问来源于stack exchange,提问作者Zanic L3
相关产品推荐
相关产品推荐

