一、项目概述
在本教程中,我们将创建一个功能完整的留言板系统,包含以下特性:
- 用户发布新留言
- 回复已有留言
- 留言列表分页显示
- 简单的管理功能
- 数据验证与安全处理
二、数据库设计
首先创建MySQL数据库和表结构:
CREATE DATABASE message_board;
USE message_board;
CREATE TABLE messages (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
content TEXT NOT NULL,
parent_id INT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX parent_index (parent_id)
);
这个简单的表结构存储留言内容、用户信息和层级关系。
三、核心功能实现
1. 数据库连接
创建db_connect.php文件处理数据库连接:
<?php
function getDBConnection() {
$host = 'localhost';
$dbname = 'message_board';
$username = 'root';
$password = '';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $pdo;
} catch(PDOException $e) {
die("数据库连接失败: " . $e->getMessage());
}
}
?>
2. 发布留言功能
创建post_message.php处理留言提交:
<?php
require_once 'db_connect.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 数据验证和过滤
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$content = filter_input(INPUT_POST, 'content', FILTER_SANITIZE_STRING);
$parent_id = filter_input(INPUT_POST, 'parent_id', FILTER_VALIDATE_INT);
if (!$username || !$email || !$content) {
die('请填写所有必填字段');
}
try {
$pdo = getDBConnection();
$stmt = $pdo->prepare("INSERT INTO messages (username, email, content, parent_id)
VALUES (?, ?, ?, ?)");
$stmt->execute([$username, $email, $content, $parent_id ?: 0]);
header('Location: index.php?success=1');
exit;
} catch(PDOException $e) {
die("留言发布失败: " . $e->getMessage());
}
}
?>
3. 显示留言列表
创建index.php显示留言和表单:
<?php
require_once 'db_connect.php';
// 分页设置
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$per_page = 10;
$offset = ($page - 1) * $per_page;
try {
$pdo = getDBConnection();
// 获取总留言数
$total_stmt = $pdo->query("SELECT COUNT(*) FROM messages WHERE parent_id = 0");
$total_messages = $total_stmt->fetchColumn();
$total_pages = ceil($total_messages / $per_page);
// 获取留言列表
$stmt = $pdo->prepare("SELECT * FROM messages WHERE parent_id = 0
ORDER BY created_at DESC LIMIT :limit OFFSET :offset");
$stmt->bindValue(':limit', $per_page, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch(PDOException $e) {
die("获取留言失败: " . $e->getMessage());
}
// 获取每条留言的回复
function getReplies($message_id) {
$pdo = getDBConnection();
$stmt = $pdo->prepare("SELECT * FROM messages WHERE parent_id = ? ORDER BY created_at ASC");
$stmt->execute([$message_id]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
?>
四、前端界面实现
在index.php中添加HTML结构:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>留言板</title>
</head>
<body>
<h1>留言板</h1>
<!-- 留言表单 -->
<form action="post_message.php" method="post">
<div>
<label for="username">姓名:</label>
<input type="text" id="username" name="username" required>
</div>
<div>
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" required>
</div>
<div>
<label for="content">留言内容:</label>
<textarea id="content" name="content" rows="4" required></textarea>
</div>
<input type="hidden" name="parent_id" value="0">
<button type="submit">发布留言</button>
</form>
<!-- 留言列表 -->
<div class="messages">
<?php foreach ($messages as $message): ?>
<div class="message">
<h3><?php echo htmlspecialchars($message['username']); ?></h3>
<p><?php echo nl2br(htmlspecialchars($message['content'])); ?></p>
<small>发布于: <?php echo $message['created_at']; ?></small>
<!-- 回复表单 -->
<form action="post_message.php" method="post" style="margin-left: 50px;">
<input type="text" name="username" placeholder="您的姓名" required>
<input type="email" name="email" placeholder="您的邮箱" required>
<textarea name="content" rows="2" placeholder="回复内容" required></textarea>
<input type="hidden" name="parent_id" value="<?php echo $message['id']; ?>">
<button type="submit">回复</button>
</form>
<!-- 显示回复 -->
<?php $replies = getReplies($message['id']); ?>
<?php if (!empty($replies)): ?>
<div class="replies">
<?php foreach ($replies as $reply): ?>
<div class="reply">
<strong><?php echo htmlspecialchars($reply['username']); ?></strong>
<p><?php echo nl2br(htmlspecialchars($reply['content'])); ?></p>
<small>回复于: <?php echo $reply['created_at']; ?></small>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<!-- 分页导航 -->
<div class="pagination">
<?php if ($page > 1): ?>
<a href="?page=<?php echo $page - 1; ?>" rel="external nofollow" >上一页</a>
<?php endif; ?>
<?php for ($i = 1; $i <= $total_pages; $i++): ?>
<a href="?page=<?php echo $i; ?>" <?php if ($i == $page) echo 'class="active"'; ?>>
<?php echo $i; ?>
</a>
<?php endfor; ?>
<?php if ($page < $total_pages): ?>
<a href="?page=<?php echo $page + 1; ?>">下一页</a>
<?php endif; ?>
</div>
</body>
</html>
五、安全增强措施
为确保应用安全,我们还需要实施以下措施:
1. 预防XSS攻击
使用htmlspecialchars()函数对所有输出到HTML的内容进行转义:
<?php
function escape($data) {
return htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
}
// 使用示例
echo '<div>' . escape($user_content) . '</div>';
?>
2. CSRF保护
添加CSRF令牌验证:
<?php
session_start();
// 生成CSRF令牌
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
// 在表单中添加CSRF令牌
?>
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
<?php
// 验证CSRF令牌
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die('CSRF令牌验证失败');
}
}
?>
3. 防止SQL注入
使用PDO预处理语句,避免直接拼接SQL查询:
<?php
// 不安全的做法(切勿使用)
$sql = "SELECT * FROM users WHERE id = " . $_GET['id']; // 容易受到SQL注入攻击
// 安全的做法
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_GET['id']]);
?>
六、部署与优化建议
完成开发后,可以考虑以下优化措施:
- 添加数据库索引优化查询性能
- 实施缓存机制(如Redis)减少数据库压力
- 对用户输入实施更严格的验证规则
- 添加图片上传和内容格式化功能
- 实施用户注册和登录系统
- 添加管理后台进行留言审核
七、总结
通过本教程,您已经学会了如何使用PHP和MySQL创建一个功能完整的留言板系统。这个系统包含了核心的CRUD(创建、读取、更新、删除)操作,以及重要的安全措施。
留言板系统是Web开发的基础练习项目,掌握了这些技能后,您可以进一步开发更复杂的Web应用程序,如博客系统、电子商务平台或社交网络应用。
记得在实际部署前进行全面测试,并根据需要添加更多功能和优化措施。

