本文目录导读:

在PHP项目中实现点赞/取消点赞功能,通常需要结合数据库和前端交互,以下是完整的实现方案:
数据库设计
创建一个点赞记录表:
CREATE TABLE likes (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL COMMENT '用户ID',
content_id INT NOT NULL COMMENT '内容ID',
content_type VARCHAR(50) NOT NULL COMMENT '内容类型,如article, comment等',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY unique_like (user_id, content_id, content_type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
表(如articles)中添加点赞数字段:
ALTER TABLE articles ADD COLUMN likes_count INT DEFAULT 0;
PHP后端实现
点赞/取消点赞接口
<?php
// like.php
session_start();
require_once 'db.php'; // 数据库连接文件
header('Content-Type: application/json');
if (!isset($_SESSION['user_id'])) {
echo json_encode(['success' => false, 'message' => '请先登录']);
exit;
}
$user_id = $_SESSION['user_id'];
$content_id = intval($_POST['content_id']);
$content_type = $_POST['content_type'] ?? 'article';
// 检查是否已点赞
$stmt = $pdo->prepare("SELECT id FROM likes WHERE user_id = ? AND content_id = ? AND content_type = ?");
$stmt->execute([$user_id, $content_id, $content_type]);
$like = $stmt->fetch();
if ($like) {
// 已点赞,取消点赞
$pdo->beginTransaction();
try {
// 删除点赞记录
$stmt = $pdo->prepare("DELETE FROM likes WHERE id = ?");
$stmt->execute([$like['id']]);
// 更新内容点赞数
$table = $content_type == 'article' ? 'articles' : 'comments';
$stmt = $pdo->prepare("UPDATE $table SET likes_count = likes_count - 1 WHERE id = ?");
$stmt->execute([$content_id]);
$pdo->commit();
echo json_encode([
'success' => true,
'liked' => false,
'likes_count' => getLikesCount($pdo, $content_id, $content_type)
]);
} catch (Exception $e) {
$pdo->rollBack();
echo json_encode(['success' => false, 'message' => '操作失败']);
}
} else {
// 未点赞,执行点赞
$pdo->beginTransaction();
try {
// 添加点赞记录
$stmt = $pdo->prepare("INSERT INTO likes (user_id, content_id, content_type) VALUES (?, ?, ?)");
$stmt->execute([$user_id, $content_id, $content_type]);
// 更新内容点赞数
$table = $content_type == 'article' ? 'articles' : 'comments';
$stmt = $pdo->prepare("UPDATE $table SET likes_count = likes_count + 1 WHERE id = ?");
$stmt->execute([$content_id]);
$pdo->commit();
echo json_encode([
'success' => true,
'liked' => true,
'likes_count' => getLikesCount($pdo, $content_id, $content_type)
]);
} catch (Exception $e) {
$pdo->rollBack();
echo json_encode(['success' => false, 'message' => '操作失败']);
}
}
function getLikesCount($pdo, $content_id, $content_type) {
$table = $content_type == 'article' ? 'articles' : 'comments';
$stmt = $pdo->prepare("SELECT likes_count FROM $table WHERE id = ?");
$stmt->execute([$content_id]);
return $stmt->fetchColumn();
}
?>
前端实现
HTML结构
<div class="like-container">
<button class="like-btn" data-content-id="123" data-content-type="article">
<i class="heart-icon">❤</i>
<span class="likes-count">0</span>
</button>
</div>
JavaScript交互
// 使用原生JavaScript
document.querySelectorAll('.like-btn').forEach(btn => {
btn.addEventListener('click', function() {
const contentId = this.dataset.contentId;
const contentType = this.dataset.contentType;
// 发送AJAX请求
fetch('like.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `content_id=${contentId}&content_type=${contentType}`
})
.then(response => response.json())
.then(data => {
if (data.success) {
// 更新UI
const heartIcon = this.querySelector('.heart-icon');
const countSpan = this.querySelector('.likes-count');
// 切换点赞状态
if (data.liked) {
this.classList.add('liked');
heartIcon.textContent = '❤️';
} else {
this.classList.remove('liked');
heartIcon.textContent = '♡';
}
// 更新点赞数
countSpan.textContent = data.likes_count;
} else {
alert(data.message);
}
})
.catch(error => console.error('Error:', error));
});
});
// 如果使用jQuery
$('.like-btn').on('click', function() {
const contentId = $(this).data('content-id');
const contentType = $(this).data('content-type');
$.ajax({
url: 'like.php',
method: 'POST',
data: {
content_id: contentId,
content_type: contentType
},
success: function(data) {
if (data.success) {
const $btn = $(this);
$btn.toggleClass('liked');
$btn.find('.likes-count').text(data.likes_count);
if (data.liked) {
$btn.find('.heart-icon').text('❤️');
} else {
$btn.find('.heart-icon').text('♡');
}
} else {
alert(data.message);
}
},
error: function() {
alert('请求失败,请重试');
}
});
});
前端CSS样式
.like-btn {
background: none;
border: 1px solid #ddd;
border-radius: 20px;
padding: 5px 15px;
cursor: pointer;
transition: all 0.3s;
display: inline-flex;
align-items: center;
gap: 5px;
}
.like-btn:hover {
background: #f0f0f0;
}
.like-btn.liked {
color: #e74c3c;
border-color: #e74c3c;
background: #fde8e8;
}
.heart-icon {
font-size: 18px;
}
.likes-count {
font-size: 14px;
font-weight: bold;
}
优化建议
缓存优化
// 使用Redis缓存点赞数
function getLikeCountCache($content_id, $content_type) {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$key = "likes:{$content_type}:{$content_id}";
$count = $redis->get($key);
if ($count === false) {
// 从数据库获取并缓存
$dbCount = getLikesCountFromDB($content_id, $content_type);
$redis->set($key, $dbCount, 3600); // 缓存1小时
return $dbCount;
}
return $count;
}
防重复点击
let isLoading = false;
$('.like-btn').on('click', function() {
if (isLoading) return;
isLoading = true;
// ... 请求代码 ...
// 请求完成后
isLoading = false;
});
完整示例代码
完整的实现还包括:
- 用户登录状态检查
- 点赞记录查询(页面加载时显示用户是否已点赞)
- 点赞动画效果
- 错误处理
如果需要完整的项目结构代码,我可以提供更详细的实现。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播