專案結構
shoutbox/
├── mysql.inc.php # 資料庫設定
├── install.php # 建表腳本 (一次性)
├── index.php # 顯示留言 + 表單
└── newshout.php # 處理送出
1. mysql.inc.php
<?php
return [
'host' => 'localhost',
'user' => 'db_user',
'pass' => 'db_pass',
'name' => 'db_name',
'charset' => 'utf8mb4',
];
2. install.php (執行後立即刪除)
<?php
require 'mysql.inc.php';
$cfg = require 'mysql.inc.php';
$pdo = new PDO("mysql:host={$cfg['host']};dbname={$cfg['name']};charset={$cfg['charset']}",
$cfg['user'], $cfg['pass'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$pdo->exec('DROP TABLE IF EXISTS `shouts`');
$pdo->exec('CREATE TABLE `shouts` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`shoutby` VARCHAR(50) NOT NULL DEFAULT "Visitor",
`shout` VARCHAR(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4');
echo "Table 'shouts' created. Enter Shoutbox";
3. index.php (顯示最新 10 則,時間格式化、防 XSS)
<?php
$cfg = require 'mysql.inc.php';
$pdo = new PDO("mysql:host={$cfg['host']};dbname={$cfg['name']};charset={$cfg['charset']}",
$cfg['user'], $cfg['pass'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$stmt = $pdo->query('SELECT * FROM `shouts` ORDER BY `id` DESC LIMIT 10');
$shouts = $stmt->fetchAll(PDO::FETCH_ASSOC);
$shouts = array_reverse($shouts); // 正序顯示 (舊在上)
?>
Shoutbox
Shoutbox
= htmlspecialchars($row['shoutby']) ?>:
= nl2br(htmlspecialchars($row['shout'])) ?>
4. newshout.php (預處理防注入、過濾標籤、重導回首頁)
<?php
$cfg = require 'mysql.inc.php';
$pdo = new PDO("mysql:host={$cfg['host']};dbname={$cfg['name']};charset={$cfg['charset']}",
$cfg['user'], $cfg['pass'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$shoutby = trim($_POST['shoutby'] ?? '');
$shout = trim($_POST['shout'] ?? '');
if ($shoutby === '' || $shoutby === 'Enter your name here') $shoutby = 'Visitor';
if ($shout !== '' && $shout !== 'Click & Shout!') {
// 移除 HTML 標籤防 XSS (保留換行)
$shout = strip_tags($shout, '
');
$stmt = $pdo->prepare('INSERT INTO `shouts` (`shoutby`, `shout`) VALUES (?, ?)');
$stmt->execute([$shoutby, $shout]);
}
header('Location: index.php');
exit;
關鍵安全點總結
- PDO 預處理:徹底防 SQL 注入。
- `htmlspecialchars` 輸出編碼:防儲存型 XSS。
- `strip_tags` 輸入過濾:雙重保險。
- CSRF 防護:簡易版可加 `honeypot` 隱藏欄位或驗證 `Referer`,正式專案請用 Token。
- 安裝腳本一次性:部署後立即刪除 `install.php`。
擴展建議
- 分頁載入 (AJAX 無限滾動)。
- 用戶系統整合 (登入後自動帶入用戶名)。
- 表情符號、圖片上傳、@提及。
- Redis 快取最新 50 條,減輕 DB 壓力。