表單驗證是 Web 安全第一道防線。本文系統講解 PHP 表單處理流程、超全域變數使用、完整驗證範例(必填、格式、長度、XSS 防護)、資料清理函數封裝,並提供生產級最佳實踐清單,助你構建健壯的表單處理機制。
welcome.html<form action="welcome.php" method="post">
Name: <input type="text" name="name"><br>
E-mail: <input type="text" name="email"><br>
<input type="submit">
</form>
welcome.php<?php // $_POST 取得表單資料 echo 'Welcome ' . htmlspecialchars($_POST['name']) . '
'; echo 'Email: ' . htmlspecialchars($_POST['email']); ?>
關鍵:輸出時 **必須** 使用 htmlspecialchars() 防 XSS。
<?php
// 初始化變數
$nameErr = $emailErr = $websiteErr = '';
$name = $email = $website = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// === 姓名驗證 ===
if (empty($_POST['name'])) {
$nameErr = '姓名為必填';
} else {
$name = cleanInput($_POST['name']);
// 僅允許字母與空格
if (!preg_match('/^[a-zA-Z ]*$/', $name)) {
$nameErr = '僅允許字母和空格';
}
}
// === Email 驗證 ===
if (empty($_POST['email'])) {
$emailErr = 'Email 為必填';
} else {
$email = cleanInput($_POST['email']);
// 簡易格式驗證
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailErr = 'Email 格式無效';
}
}
// === 網址驗證(選填) ===
if (!empty($_POST['website'])) {
$website = cleanInput($_POST['website']);
// URL 格式驗證
if (!filter_var($website, FILTER_VALIDATE_URL)) {
$websiteErr = 'URL 格式無效';
}
}
// === 驗證通過處理 ===
if (!$nameErr && !$emailErr && !$websiteErr) {
// 業務邏輯:寫入資料庫、發送郵件等
echo "提交成功!
";
echo "Name: $name
Email: $email
Website: $website";
exit; // 或重導向防重複提交
}
}
/**
* 統一資料清理函數
*/
function cleanInput($data) {
$data = trim($data); // 移除首尾空白
$data = stripslashes($data); // 移除反斜線(魔術引號殘留)
$data = htmlspecialchars($data); // HTML 實體編碼
return $data;
}
?>
<!DOCTYPE html>
<html>
<head><title>PHP 表單驗證</title></head>
<body>
<h2>PHP 驗證範例</h2>
<p><span style="color:red">* 必填欄位</span></p>
<form method="post" action="">
姓名:<input type="text" name="name" value="">
<span style="color:red">* </span><br><br>
Email:<input type="text" name="email" value="">
<span style="color:red">* </span><br><br>
網址:<input type="text" name="website" value="">
<span style="color:red"></span><br><br>
<input type="submit" value="提交">
</form>
</body>
</html>
| 函數 | 作用 | 必要性 |
|---|---|---|
| trim() | 移除首尾空白、換行、Tab | ✅ 必須 |
| stripslashes() | 移除魔術引號添加的反斜線 | ⚠️ 視環境(PHP 5.4+ 已移除) |
| htmlspecialchars() | 特殊字元轉 HTML 實體 | ✅ 輸出時必須 |
// Email filter_var($email, FILTER_VALIDATE_EMAIL) // URL filter_var($url, FILTER_VALIDATE_URL) // IP filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) // 整數範圍 filter_var($age, FILTER_VALIDATE_INT, ['options' => ['min_range' => 18, 'max_range' => 100]]) // 布林 filter_var($val, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)
優勢:C 層實作效能高、支援國際化格式、維護成本低。
| 需求 | 模式 | 說明 |
|---|---|---|
| 中文姓名 | /^[\x{4e00}-\x{9fa5}]{2,10}$/u | Unicode 範圍 |
| 手機號 | /^1[3-9]\d{9}$/ | 大陸手機號 |
| 身分證 | /^[A-Z][12]\d{8}$/ | 台灣身分證 |
| 密碼強度 | /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/ | 大小寫+數字 8+ 位 |
| 郵遞區號 | /^\d{3,5}$/ | 3-5 位數字 |
<input type="hidden" name="csrf_token" value="">,提交時驗證header('Location: success.php') 重導向getimagesize() 確認圖片、重新編碼儲存<input name="hp_field" style="display:none">,有值即為機器人[✅] 所有輸出經 htmlspecialchars() [✅] 使用 filter_var() 替代手寫正則 [✅] 驗證失敗保留用戶輸入 (value="") [✅] 錯誤訊息具體明確(非「輸入錯誤」) [✅] 必填/選填視覺區分(* 標記) [✅] POST-Redirect-GET 防重複提交 [✅] CSRF Token 保護敏感操作 [✅] 敏感操作需再次驗證密碼/2FA [✅] 伺服器端驗證為準,前端驗證僅 UX 輔助 [✅] 記錄驗證失敗日誌(安全審計)
PHP 表單驗證核心原則:**永遠不信任用戶輸入**。採用「清理 → 驗證 → 處理」三階段管線,善用內建 filter_var、htmlspecialchars、password_hash 等安全函數,配合 CSRF Token、PRG 模式、速率限制,即可構建企業級表單安全防線。建議封裝為 FormValidator 類別,統一專案驗證標準。