PHP 实战:留言板

综合运用 PHP 表单处理、PDO 数据库、Session 等知识,构建一个完整的留言板应用。

项目结构

实例
guestbook/
├── index.php      # 留言列表 + 发表表单
├── submit.php     # 处理提交
├── delete.php     # 删除留言(管理员)
├── db.php         # 数据库连接
└── style.css      # 样式
``

数据库设计

`sql CREATE TABLE messages ( id INT AUTO_INCREMENT PRIMARY KEY, nickname VARCHAR(50) NOT NULL, content TEXT NOT NULL, ip VARCHAR(45) DEFAULT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); `

数据库连接(db.php)

`php function getDB(): PDO { static $pdo = null; if ($pdo === null) { $pdo = new PDO( 'mysql:host=localhost;dbname=guestbook;charset=utf8mb4', 'root', 'password', [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC] ); } return $pdo; } `

留言列表与表单(index.php)

`php require 'db.php';

$pdo = getDB(); $messages = $pdo->query("SELECT * FROM messages ORDER BY id DESC LIMIT 50") ->fetchAll();

$error = $_SESSION['error'] ?? ''; $success = $_SESSION['success'] ?? ''; unset($_SESSION['error'], $_SESSION['success']); `

`html <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><title>留言板</title></head> <body> <h1>留言板</h1>

<?php if ($success): ?> <p style="color:green"><?= htmlspecialchars($success) ?></p> <?php endif; ?> <?php if ($error): ?> <p style="color:red"><?= htmlspecialchars($error) ?></p> <?php endif; ?>

<form action="submit.php" method="POST"> <input type="text" name="nickname" placeholder="昵称" maxlength="50" required> <textarea name="content" placeholder="留言内容..." maxlength="500" required></textarea> <button type="submit">发表留言</button> </form>

<hr> <?php foreach ($messages as $msg): ?> <div class="message"> <strong><?= htmlspecialchars($msg['nickname']) ?></strong> <time><?= $msg['created_at'] ?></time> <p><?= nl2br(htmlspecialchars($msg['content'])) ?></p> </div> <?php endforeach; ?> </body> </html> `

处理提交(submit.php)

`php session_start(); require 'db.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') { header('Location: index.php'); exit; }

$nickname = trim($_POST['nickname'] ?? ''); $content = trim($_POST['content'] ?? ''); $ip = $_SERVER['REMOTE_ADDR'];

// 验证 if (empty($nickname) || mb_strlen($nickname) > 50) { $_SESSION['error'] = '昵称不合法'; header('Location: index.php'); exit; } if (empty($content) || mb_strlen($content) > 500) { $_SESSION['error'] = '内容不合法'; header('Location: index.php'); exit; }

// 简单防刷:同一 IP 60 秒内只能发一条 $stmt = getDB()->prepare( "SELECT COUNT(*) FROM messages WHERE ip = ? AND created_at > DATE_SUB(NOW(), INTERVAL 60 SECOND)" ); $stmt->execute([$ip]); if ($stmt->fetchColumn() > 0) { $_SESSION['error'] = '发言太频繁,请稍后再试'; header('Location: index.php'); exit; }

// 插入 $stmt = getDB()->prepare("INSERT INTO messages (nickname, content, ip) VALUES (?, ?, ?)"); $stmt->execute([$nickname, $content, $ip]);

$_SESSION['success'] = '留言成功!'; header('Location: index.php'); exit; `

删除留言(delete.php)

``php session_start(); require 'db.php';

// 简单管理员验证 if (($_SESSION['is_admin'] ?? false) !== true) { http_response_code(403); die('无权限'); }

$id = (int)($_GET['id'] ?? 0); if ($id > 0) { $stmt = getDB()->prepare("DELETE FROM messages WHERE id = ?"); $stmt->execute([$id]); }

header('Location: index.php'); exit;

功能扩展思路

  • 添加验证码防止机器人刷留言
  • 支持 Markdown 格式留言内容
  • 管理员后台审核留言
  • 邮件通知新留言
  • 留言点赞功能