表單驗證是 Web 開發的基礎防線。本文提供三個生產環境可用的 PHP 驗證函數:Email 格式、使用者名稱必須以字母開頭、密碼僅限英數組合,採用 preg_match (PCRE) 實現,並解析正則細節與潛在改進點。
<?php
/**
* 驗證 Email 格式
* 支援常見格式:user@domain.com, user.name@sub.domain.co.uk
* 注意:嚴格 RFC 5322 正則極其複雜,此處採用實用主義簡化版
*/
function is_email(string $email): bool {
// 修正:原範例 [a-za-z] 應為 [a-zA-Z];域名部分允許連字號、多級子域
$pattern = '/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/';
return (bool) preg_match($pattern, $email);
}
/**
* 驗證使用者名稱
* 規則:字母開頭,長度 4-20,僅允許字母、數字、底線、點
* 原範例 {3,19} 配合開頭 1 字元 = 總長 4-20
*/
function is_username(string $username): bool {
// ^[a-zA-Z] 首字母必須為字母
// [a-zA-Z0-9._]{3,19} 後續 3-19 字元:字母數字底線點
// $ 結尾
$pattern = '/^[a-zA-Z][a-zA-Z0-9._]{3,19}$/';
return (bool) preg_match($pattern, $username);
}
/**
* 驗證密碼
* 規則:4-20 位,僅限字母、數字、底線 (\w = [a-zA-Z0-9_])
* 注意:原範例 /^(w){4,20}$/ 寫法錯誤,應為 \w 或 [a-zA-Z0-9_]
* 建議:生產環境應要求「含大小寫+數字+特殊符號」,此處僅示範基礎邏輯
*/
function is_password(string $password): bool {
$pattern = '/^[a-zA-Z0-9_]{4,20}$/'; // 等價 /^\w{4,20}$/ (需單引號避免 \w 被 PHP 轉義)
return (bool) preg_match($pattern, $password);
}
// === 測試範例 ===
$tests = [
'email' => ['test@example.com', 'invalid@', 'user.name@sub.domain.org'],
'username' => ['JohnDoe', '123John', 'Jo', 'VeryLongUsername123456', 'user_name'],
'password' => ['Pass123', '1234', 'VeryLongPassword12345678901', 'pass word'],
];
foreach ($tests as $type => $cases) {
echo "<h3>$type 驗證測試</h3>";
foreach ($cases as $val) {
$fn = "is_$type";
$ok = $fn($val) ? '✅ 通過' : '❌ 失敗';
echo htmlspecialchars($val) . " => $ok<br>";
}
}
?>
/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/| 片段 | 含義 |
|---|---|
^ | 字串開始 |
[a-zA-Z0-9._%+-]+ | 本地部:字母數字及 ._%+-,至少一個 |
@ | 字面 @ 符號 |
[a-zA-Z0-9.-]+ | 域名主體:字母數字、點、連字號 |
\. | 字面點 (分隔 TLD) |
[a-zA-Z]{2,} | 頂級域:至少兩字母 (com, cn, org, io...) |
$ | 字串結束 |
局限: 不支援國際化域名 (IDN)、IP 域名、帶註釋格式。嚴格場景建議用 filter_var($email, FILTER_VALIDATE_EMAIL) 或專用庫 (egulias/EmailValidator)。
/^[a-zA-Z][a-zA-Z0-9._]{3,19}$/. 與底線 _:符合常見習慣 (如 john.doe, jane_doe)。VARCHAR(20) 或 50)。安全補充: 應加入黑名單過濾保留字 (admin, root, api 等) 及敏感詞。
/^[a-zA-Z0-9_]{4,20}$/ ⚠️ 僅供教學,生產環境勿用原範例 /^(w){4,20}$/ 有語法錯誤 (w 字面匹配),正確為 \w (需單引號字串 '/^\w{4,20}$/')。
現代密碼策略建議 (OWASP/NIST):**
password_hash() (bcrypt/argon2id) + password_verify()**<?php
// 現代註冊流程範例
if (strlen($password) < 12) throw new Exception('密碼至少 12 字元');
if (in_array($password, $commonPasswords)) throw new Exception('密碼過於常見');
$hash = password_hash($password, PASSWORD_ARGON2ID); // PHP 7.2+
// 登入驗證
if (password_verify($inputPassword, $storedHash)) { /* 成功 */ }
?>
filter_var 內建驗證器:Email、URL、IP、布林等優先用內建。\w, \d)。扎實的輸入驗證,是系統安全與資料品質的第一道防線。