表單處理是 PHP 入門必經之路,但新手常踩坑:超全域變數大小寫、中文亂碼、SQL 注入漏洞。本文整理常見錯誤並提供現代最佳實踐。
<?php
// conn.php - 資料庫連線(舊式 mysql_* 已棄用)
$conn = @mysql_connect('localhost', 'root', '') or die('資料庫連線錯誤');
mysql_select_db('bbs', $conn);
mysql_query("set names 'GBK'"); // 使用 GBK 編碼
// add2.php - 表單處理
include('conn.php');
if ($_POST['submit']) { // 錯誤:應檢查 $_SERVER['REQUEST_METHOD']
$sql = "insert into test (id,name,sex) values ('','$_POST[name]','$_POST[sex]')";
mysql_query($sql);
echo '成功!';
}
?>
<form action="add2.php" method="post">
<input type="text" name="name" value="輸入名字" />
<input type="text" name="sex" value="輸入性別" />
<input type="submit" name="submit" value="提交" />
</form>
| 問題 | 原因 | 正確做法 |
|---|---|---|
| 超全域變數大小寫 | PHP 變數區分大小寫,$_POST['name'] ≠ $_POST['NAME'] | 統一使用小寫鍵名,對應 HTML name 屬性 |
| 直接插值 SQL | 極高風險 SQL 注入 | 使用 Prepared Statement (PDO/mysqli) |
| 編碼不一致 | 資料庫 GBK、頁面 UTF-8、連線未設字元集 | 全鏈路統一 UTF-8 (utf8mb4) |
使用已棄用 mysql_* | PHP 7.0 移除,不安全 | 改用 PDO 或 mysqli |
| 缺乏輸入驗證 | 直接信任使用者輸入 | 伺服器端驗證 + 過濾/轉義 |
db.php<?php
// db.php
$dsn = 'mysql:host=localhost;dbname=bbs;charset=utf8mb4';
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO($dsn, 'root', '', $opt);
} catch (PDOException $e) {
die('資料庫連線失敗:' . $e->getMessage());
}
add.php<?php
require_once 'db.php';
$message = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$sex = trim($_POST['sex'] ?? '');
// 簡單驗證
if ($name === '' || $sex === '') {
$message = '請填寫完整資料';
} else {
try {
$stmt = $pdo->prepare('INSERT INTO test (name, sex) VALUES (?, ?)');
$stmt->execute([$name, $sex]);
$message = '新增成功!ID: ' . $pdo->lastInsertId();
} catch (PDOException $e) {
$message = '新增失敗:' . $e->getMessage();
}
}
}
?>
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>表單測試</title></head><body>
<h2>會員新增</h2>
<?php if ($message): ?><p style="color:green"><?= htmlspecialchars($message) ?></p><?php endif; ?>
<form method="post">
<label>姓名:<input type="text" name="name" required></label><br>
<label>性別:<input type="text" name="sex" required></label><br>
<button type="submit">送出</button>
</form>
</body></html>
htmlspecialchars()。mb_strlen() 驗證。display_errors,記錄至日誌。表單處理看似簡單,實則涉及編碼、安全、資料庫驅動等多層面知識。摒棄舊式 mysql_*、採用 PDO Prepared Statement、統一 UTF-8 編碼、嚴格驗證輸入,是寫出安全可維護 PHP 程式的基石。