本文展示一個結合 PHP (後端) + jQuery (前端 AJAX) 的留言板增刪完整範例,採用非同步請求無刷新體驗,並修正原始碼中的 SQL 注入風險與過時函式。
CREATE TABLE `messages` (
`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`content` TEXT NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
<?php
header('Content-Type: application/json; charset=utf-8');
require_once 'db.php'; // PDO 連線
$action = $_POST['action'] ?? $_GET['action'] ?? '';
try {
switch ($action) {
case 'list':
$stmt = $pdo->query("SELECT id, content, created_at FROM messages ORDER BY id DESC LIMIT 30");
echo json_encode(['status' => 'ok', 'data' => $stmt->fetchAll(PDO::FETCH_ASSOC)]);
break;
case 'add':
$content = trim($_POST['content'] ?? '');
if ($content === '') throw new Exception('內容不可為空');
$stmt = $pdo->prepare("INSERT INTO messages (content) VALUES (?)");
$stmt->execute([$content]);
echo json_encode(['status' => 'ok', 'id' => $pdo->lastInsertId()]);
break;
case 'delete':
$id = (int)($_POST['id'] ?? $_GET['id'] ?? 0);
if ($id <= 0) throw new Exception('無效 ID');
$stmt = $pdo->prepare("DELETE FROM messages WHERE id = ?");
$stmt->execute([$id]);
echo json_encode(['status' => 'ok']);
break;
default:
throw new Exception('未知操作');
}
} catch (Exception $e) {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}
?>
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>留言板</title>
<style>
body {font-family: sans-serif; max-width: 600px; margin: 2rem auto;}
.msg {border-bottom: 1px solid #eee; padding: 1rem 0; display: flex; justify-content: space-between;}
.msg-content {flex: 1;} .msg-time {color: #888; font-size: 0.85rem; margin-left: 1rem;}
.msg-del {color: #c00; cursor: pointer; text-decoration: none;}
textarea {width: 100%; height: 80px; margin-bottom: 0.5rem;}
button {padding: 0.5rem 1rem; cursor: pointer;}
.error {color: #c00; margin: 0.5rem 0;}
</style>
</head><body>
<h1>即時留言板</h1>
<div id="error" class="error"></div>
<form id="msgForm">
<textarea name="content" placeholder="輸入留言..." required></textarea>
<button type="submit">發送</button>
</form>
<div id="msgList">載入中...</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
<script>
$(function() {
const $list = $('#msgList'), $err = $('#error');
function load() {
$.post('api.php', {action: 'list'}, function(res) {
if (res.status === 'ok') {
$list.html(res.data.map(m =>
``
).join(''));
} else { showErr(res.message); }
}, 'json');
}
$('#msgForm').on('submit', function(e) {
e.preventDefault();
const content = $(this).find('textarea').val().trim();
if (!content) return showErr('請輸入內容');
$.post('api.php', {action: 'add', content}, function(res) {
if (res.status === 'ok') { $('textarea').val(''); load(); }
else showErr(res.message);
}, 'json');
});
$list.on('click', '.msg-del', function() {
if (!confirm('確定刪除?')) return;
const id = $(this).data('id');
$.post('api.php', {action: 'delete', id}, function(res) {
if (res.status === 'ok') load();
else showErr(res.message);
}, 'json');
});
function showErr(msg) { $err.text(msg).fadeIn().delay(3000).fadeOut(); }
function escapeHtml(t) { return $('').text(t).html(); }
load();
});
</script>
</body></html>
關鍵改進點
- PDO 預處理:徹底防 SQL 注入,替代過時
mysql_* 函式。
- AJAX 非同步:新增/刪除/列表無需重整頁面。
- 統一 JSON API:前後端分離,易於擴充(如加入編輯、分頁)。
- XSS 防護:前端
escapeHtml 轉義輸出,後端儲存原始資料。
- 錯誤處理:try-catch 捕獲異常,回傳標準化錯誤格式。
db.php 範例
<?php
$pdo = new PDO(
"mysql:host=localhost;dbname=testdb;charset=utf8mb4",
"username", "password",
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false]
);
?>
- 上一篇文章: PHP 檔案上傳完整指南:從表單建構到多檔案處理實戰
- 下一篇文章: PHP 產生數字驗證碼防惡意註冊完整實作教學