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 格式留言内容
- 管理员后台审核留言
- 邮件通知新留言
- 留言点赞功能