php实现评论功能
数据库设计
创建评论表存储评论数据,基本字段包括评论ID、用户ID、内容、创建时间、关联文章ID等。示例SQL:
CREATE TABLE comments (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
content TEXT NOT NULL,
article_id INT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (article_id) REFERENCES articles(id)
);
表单处理
创建评论提交表单,通常包含内容输入框和隐藏的文章ID字段。HTML示例:
<form method="POST" action="add_comment.php">
<textarea name="content" required></textarea>
<input type="hidden" name="article_id" value="<?php echo $article_id; ?>">
<button type="submit">提交评论</button>
</form>
后端处理
在add_comment.php中处理表单提交,验证数据并存入数据库:
<?php
session_start();
require 'db_connection.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$content = htmlspecialchars(trim($_POST['content']));
$article_id = (int)$_POST['article_id'];
$user_id = $_SESSION['user_id'];
if (!empty($content)) {
$stmt = $pdo->prepare("INSERT INTO comments (user_id, content, article_id) VALUES (?, ?, ?)");
$stmt->execute([$user_id, $content, $article_id]);
header("Location: article.php?id=$article_id");
exit;
}
}
?>
显示评论
在文章页面查询并显示相关评论:
<?php
$article_id = (int)$_GET['id'];
$stmt = $pdo->prepare("SELECT c.*, u.username FROM comments c
JOIN users u ON c.user_id = u.id
WHERE c.article_id = ? ORDER BY c.created_at DESC");
$stmt->execute([$article_id]);
$comments = $stmt->fetchAll();
foreach ($comments as $comment) {
echo '<div class="comment">';
echo '<h4>' . htmlspecialchars($comment['username']) . '</h4>';
echo '<p>' . htmlspecialchars($comment['content']) . '</p>';
echo '<small>' . $comment['created_at'] . '</small>';
echo '</div>';
}
?>
安全措施
实施XSS防护和CSRF保护:
// 在所有输出上使用htmlspecialchars
// 添加CSRF令牌
$_SESSION['token'] = bin2hex(random_bytes(32));
// 在表单中添加
<input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>">
// 验证时检查
if (!hash_equals($_SESSION['token'], $_POST['token'])) {
die('CSRF验证失败');
}
分页功能
对大量评论实现分页:
$per_page = 10;
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$offset = ($page - 1) * $per_page;
$stmt = $pdo->prepare("SELECT SQL_CALC_FOUND_ROWS c.*, u.username
FROM comments c JOIN users u ON c.user_id = u.id
WHERE c.article_id = ?
ORDER BY c.created_at DESC
LIMIT ? OFFSET ?");
$stmt->execute([$article_id, $per_page, $offset]);
$comments = $stmt->fetchAll();
$total = $pdo->query("SELECT FOUND_ROWS()")->fetchColumn();
$total_pages = ceil($total / $per_page);






