一、项目概述
在本教程中,我们将创建一个功能完整的留言板系统,包含以下特性:
- 用户发布新留言
- 回复已有留言
- 留言列表分页显示
- 简单的管理功能
- 数据验证与安全处理
二、数据库设计
首先创建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应用程序,如博客系统、电子商务平台或社交网络应用。
记得在实际部署前进行全面测试,并根据需要添加更多功能和优化措施。