Skip to content

14.1 实战 1:简单留言本(表单 + 数据库 + 展示)

本章节将实现一个简单的留言本系统,包括表单提交、数据库存储和留言展示功能。

项目结构

simple-message-board/
├── db.php              # 数据库连接文件
├── index.php           # 留言展示页面
├── add_message.php     # 留言提交处理
└── css/
    └── style.css       # 样式文件

1. 数据库配置

创建 db.php 文件,用于数据库连接:

php
<?php
// db.php
function getDbConnection() {
    $servername = "localhost";
    $username = "root";
    $password = "";
    $dbname = "php_tutorial";
    
    // 创建连接
    $conn = new mysqli($servername, $username, $password, $dbname);
    
    // 检查连接
    if ($conn->connect_error) {
        die("连接失败: " . $conn->connect_error);
    }
    
    // 设置字符集
    $conn->set_charset("utf8mb4");
    
    return $conn;
}
?>

2. 数据库表结构

创建 messages 表:

sql
CREATE TABLE messages (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL,
    message TEXT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

3. 样式文件

创建 css/style.css 文件:

css
/* style.css */
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

body {
    font-family: Arial, sans-serif;
    line-height: 1.6;
    color: #333;
    background-color: #f4f4f4;
}

.container {
    max-width: 800px;
    margin: 0 auto;
    padding: 20px;
}

h1 {
    text-align: center;
    color: #333;
    margin-bottom: 30px;
}

.message-form {
    background-color: #fff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    margin-bottom: 30px;
}

.form-group {
    margin-bottom: 15px;
}

label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
}

input[type="text"],
input[type="email"],
textarea {
    width: 100%;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-size: 16px;
}

textarea {
    height: 150px;
    resize: vertical;
}

button[type="submit"] {
    background-color: #4CAF50;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 16px;
}

button[type="submit"]:hover {
    background-color: #45a049;
}

.messages {
    background-color: #fff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.message {
    border-bottom: 1px solid #eee;
    padding: 15px 0;
}

.message:last-child {
    border-bottom: none;
}

.message-header {
    display: flex;
    justify-content: space-between;
    margin-bottom: 10px;
}

.message-name {
    font-weight: bold;
    color: #333;
}

.message-time {
    font-size: 12px;
    color: #999;
}

.message-content {
    color: #666;
    line-height: 1.5;
}

.error {
    background-color: #f8d7da;
    color: #721c24;
    padding: 10px;
    border-radius: 4px;
    margin-bottom: 15px;
    border: 1px solid #f5c6cb;
}

.success {
    background-color: #d4edda;
    color: #155724;
    padding: 10px;
    border-radius: 4px;
    margin-bottom: 15px;
    border: 1px solid #c3e6cb;
}

4. 留言展示页面

创建 index.php 文件:

php
<?php
// index.php
require_once 'db.php';
$conn = getDbConnection();

// 获取留言列表
$sql = "SELECT * FROM messages ORDER BY created_at DESC";
$result = $conn->query($sql);

$messages = [];
if ($result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
        $messages[] = $row;
    }
}

$conn->close();
?>

<!DOCTYPE html>
<html>
<head>
    <title>简单留言本</title>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <div class="container">
        <h1>简单留言本</h1>
        
        <!-- 留言表单 -->
        <div class="message-form">
            <h2>发表留言</h2>
            
            <?php if (isset($_GET['error'])): ?>
                <div class="error"><?php echo $_GET['error']; ?></div>
            <?php endif; ?>
            
            <?php if (isset($_GET['success'])): ?>
                <div class="success"><?php echo $_GET['success']; ?></div>
            <?php endif; ?>
            
            <form action="add_message.php" method="post">
                <div class="form-group">
                    <label>姓名: <input type="text" name="name" required></label>
                </div>
                <div class="form-group">
                    <label>邮箱: <input type="email" name="email" required></label>
                </div>
                <div class="form-group">
                    <label>留言: <textarea name="message" required></textarea></label>
                </div>
                <button type="submit" name="submit">发表留言</button>
            </form>
        </div>
        
        <!-- 留言列表 -->
        <div class="messages">
            <h2>留言列表</h2>
            
            <?php if (empty($messages)): ?>
                <p>暂无留言,快来发表第一条留言吧!</p>
            <?php else: ?>
                <?php foreach ($messages as $message): ?>
                    <div class="message">
                        <div class="message-header">
                            <span class="message-name"><?php echo htmlspecialchars($message['name']); ?></span>
                            <span class="message-time"><?php echo $message['created_at']; ?></span>
                        </div>
                        <div class="message-content"><?php echo nl2br(htmlspecialchars($message['message'])); ?></div>
                    </div>
                <?php endforeach; ?>
            <?php endif; ?>
        </div>
    </div>
</body>
</html>

5. 留言提交处理

创建 add_message.php 文件:

php
<?php
// add_message.php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['submit'])) {
    require_once 'db.php';
    $conn = getDbConnection();
    
    // 获取表单数据
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];
    
    // 验证数据
    if (empty($name) || empty($email) || empty($message)) {
        header('Location: index.php?error=所有字段都不能为空');
        exit;
    }
    
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        header('Location: index.php?error=邮箱格式不正确');
        exit;
    }
    
    // 准备 SQL 语句
    $stmt = $conn->prepare("INSERT INTO messages (name, email, message) VALUES (?, ?, ?)");
    $stmt->bind_param("sss", $name, $email, $message);
    
    // 执行 SQL 语句
    if ($stmt->execute()) {
        header('Location: index.php?success=留言发表成功');
        exit;
    } else {
        header('Location: index.php?error=留言发表失败,请重试');
        exit;
    }
    
    $stmt->close();
    $conn->close();
} else {
    header('Location: index.php');
    exit;
}
?>

6. 运行项目

  1. 确保数据库已创建并创建了 messages
  2. 启动本地服务器
  3. 访问 http://localhost/simple-message-board/index.php
  4. 填写表单并发表留言
  5. 查看留言列表

7. 功能扩展

1. 添加分页功能

修改 index.php 文件,添加分页功能:

php
<?php
// index.php
require_once 'db.php';
$conn = getDbConnection();

// 分页设置
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$perPage = 5;
$offset = ($page - 1) * $perPage;

// 获取留言总数
$sql = "SELECT COUNT(*) as total FROM messages";
$result = $conn->query($sql);
$row = $result->fetch_assoc();
$totalMessages = $row['total'];
$totalPages = ceil($totalMessages / $perPage);

// 获取留言列表
$sql = "SELECT * FROM messages ORDER BY created_at DESC LIMIT ? OFFSET ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ii", $perPage, $offset);
$stmt->execute();
$result = $stmt->get_result();

$messages = [];
if ($result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
        $messages[] = $row;
    }
}

$stmt->close();
$conn->close();
?>

<!-- 在留言列表下方添加分页 -->
<?php if ($totalPages > 1): ?>
    <div class="pagination" style="margin-top: 20px; text-align: center;">
        <?php if ($page > 1): ?>
            <a href="index.php?page=<?php echo $page - 1; ?>" style="margin: 0 5px; text-decoration: none; color: #4CAF50;">上一页</a>
        <?php endif; ?>
        
        <?php for ($i = 1; $i <= $totalPages; $i++): ?>
            <a href="index.php?page=<?php echo $i; ?>" style="margin: 0 5px; text-decoration: none; color: <?php echo $i == $page ? '#4CAF50' : '#333'; ?>;">
                <?php echo $i; ?>
            </a>
        <?php endfor; ?>
        
        <?php if ($page < $totalPages): ?>
            <a href="index.php?page=<?php echo $page + 1; ?>" style="margin: 0 5px; text-decoration: none; color: #4CAF50;">下一页</a>
        <?php endif; ?>
    </div>
<?php endif; ?>

2. 添加留言删除功能

修改 index.php 文件,添加删除按钮:

php
<!-- 在留言内容下方添加删除按钮 -->
<div class="message-actions" style="margin-top: 10px;">
    <a href="delete_message.php?id=<?php echo $message['id']; ?>" style="color: #dc3545; text-decoration: none; font-size: 14px;" onclick="return confirm('确定要删除这条留言吗?');">删除</a>
</div>

创建 delete_message.php 文件:

php
<?php
// delete_message.php
if (isset($_GET['id'])) {
    $messageId = $_GET['id'];
    
    require_once 'db.php';
    $conn = getDbConnection();
    
    // 准备 SQL 语句
    $stmt = $conn->prepare("DELETE FROM messages WHERE id = ?");
    $stmt->bind_param("i", $messageId);
    
    // 执行 SQL 语句
    if ($stmt->execute()) {
        header('Location: index.php?success=留言删除成功');
        exit;
    } else {
        header('Location: index.php?error=留言删除失败,请重试');
        exit;
    }
    
    $stmt->close();
    $conn->close();
} else {
    header('Location: index.php');
    exit;
}
?>

3. 添加留言编辑功能

修改 index.php 文件,添加编辑按钮:

php
<!-- 在留言内容下方添加编辑按钮 -->
<div class="message-actions" style="margin-top: 10px;">
    <a href="edit_message.php?id=<?php echo $message['id']; ?>" style="color: #007bff; text-decoration: none; font-size: 14px; margin-right: 10px;">编辑</a>
    <a href="delete_message.php?id=<?php echo $message['id']; ?>" style="color: #dc3545; text-decoration: none; font-size: 14px;" onclick="return confirm('确定要删除这条留言吗?');">删除</a>
</div>

创建 edit_message.php 文件:

php
<?php
// edit_message.php
if (!isset($_GET['id'])) {
    header('Location: index.php');
    exit;
}

$messageId = $_GET['id'];

require_once 'db.php';
$conn = getDbConnection();

// 获取留言信息
$stmt = $conn->prepare("SELECT * FROM messages WHERE id = ?");
$stmt->bind_param("i", $messageId);
$stmt->execute();
$result = $stmt->get_result();

if ($result->num_rows === 0) {
    header('Location: index.php?error=留言不存在');
    exit;
}

$message = $result->fetch_assoc();

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['submit'])) {
    // 获取表单数据
    $name = $_POST['name'];
    $email = $_POST['email'];
    $messageContent = $_POST['message'];
    
    // 验证数据
    if (empty($name) || empty($email) || empty($messageContent)) {
        header('Location: edit_message.php?id=' . $messageId . '&error=所有字段都不能为空');
        exit;
    }
    
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        header('Location: edit_message.php?id=' . $messageId . '&error=邮箱格式不正确');
        exit;
    }
    
    // 准备 SQL 语句
    $stmt = $conn->prepare("UPDATE messages SET name = ?, email = ?, message = ? WHERE id = ?");
    $stmt->bind_param("sssi", $name, $email, $messageContent, $messageId);
    
    // 执行 SQL 语句
    if ($stmt->execute()) {
        header('Location: index.php?success=留言编辑成功');
        exit;
    } else {
        header('Location: edit_message.php?id=' . $messageId . '&error=留言编辑失败,请重试');
        exit;
    }
}

$stmt->close();
$conn->close();
?>

<!DOCTYPE html>
<html>
<head>
    <title>编辑留言</title>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <div class="container">
        <h1>编辑留言</h1>
        
        <div class="message-form">
            <?php if (isset($_GET['error'])): ?>
                <div class="error"><?php echo $_GET['error']; ?></div>
            <?php endif; ?>
            
            <form action="" method="post">
                <div class="form-group">
                    <label>姓名: <input type="text" name="name" value="<?php echo htmlspecialchars($message['name']); ?>" required></label>
                </div>
                <div class="form-group">
                    <label>邮箱: <input type="email" name="email" value="<?php echo htmlspecialchars($message['email']); ?>" required></label>
                </div>
                <div class="form-group">
                    <label>留言: <textarea name="message" required><?php echo htmlspecialchars($message['message']); ?></textarea></label>
                </div>
                <button type="submit" name="submit">保存修改</button>
                <a href="index.php" style="margin-left: 10px; text-decoration: none; color: #666;">取消</a>
            </form>
        </div>
    </div>
</body>
</html>

8. 注意事项

  1. 安全性

    • 使用 htmlspecialchars 防止 XSS 攻击
    • 使用预处理语句防止 SQL 注入
    • 验证用户输入
  2. 性能

    • 使用分页减少数据传输
    • 优化数据库查询
  3. 用户体验

    • 提供清晰的错误提示
    • 显示操作成功的反馈
    • 确认删除操作
  4. 兼容性

    • 确保在不同浏览器中正常显示
    • 响应式设计,适配不同屏幕尺寸

练习

  1. 实现完整的简单留言本系统
  2. 添加分页功能
  3. 添加留言删除功能
  4. 添加留言编辑功能
  5. 优化用户界面和体验

© 2026 编程马·菜鸟教程 版权所有