首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 入門

PHP 表單驗證:姓名、Email、URL 正則表達式與 filter_var 實務應用

     編輯:PHP 入門

PHP 表單驗證:姓名、Email、URL 正則表達式與 filter_var 實務應用

表單驗證核心在於「格式檢查」與「業務規則」。PHP 提供強大的 preg_match() 正則引擎與 filter_var() 內建過濾器,兩者互補,能精準驗證姓名、Email、URL 等常見欄位。

preg_match() 正則驗證基礎

preg_match(string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0): int|false
  • 回傳 1 符合、0 不符合、false 錯誤
  • $matches[0] 完整匹配、$matches[1] 第一個捕獲組...
  • 模式需以分隔符包裹:/pattern/, #pattern#, ~pattern~

姓名驗證

英文姓名(字母+空格)

<?php
$name = trim($_POST['name'] ?? '');
if (!preg_match('/^[A-Za-z\s]+$/', $name)) {
    $nameErr = '英文姓名僅允許字母與空格';
}
// 允許連字號、撇號(如 O'Connor, Jean-Paul)
if (!preg_match("/^[A-Za-z\s'-]+$/", $name)) { ... }

中文姓名(含中英文混合)

<?php
// 基本中文字符範圍 \u4e00-\u9fa5(CJK Unified Ideographs)
if (!preg_match('/^[\p{Han}A-Za-z\s]+$/u', $name)) {
    $nameErr = '姓名僅允許中英文字母與空格';
}
// 更完整:支援擴展區、生僻字
if (!preg_match('/^[\p{Han}\p{L}\s]+$/u', $name)) { ... }

實務建議

  • 長度限制:mb_strlen($name) <= 50
  • 禁止控制字元:!preg_match('/[\x00-\x1F\x7F]/', $name)
  • 去除多餘空白:preg_replace('/\s+/', ' ', $name)

Email 驗證

filter_var() 內建驗證(推薦)

<?php
$email = trim($_POST['email'] ?? '');
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $emailErr = 'Email 格式不正確';
}
// 選項:禁止特定域名、要求特定 TLD
$options = [
    'options' => ['regexp' => '/@(gmail|yahoo|outlook)\.com$/i']
];
// filter_var($email, FILTER_VALIDATE_EMAIL, $options); // PHP 8.1+

優點: 符合 RFC 5322/6531、支援國際化域名(IDN)、維護成本低。

正則驗證(特定需求)

<?php
// 簡易版(教學常見)
if (!preg_match('/^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,}$/', $email)) { ... }

// 較嚴格(RFC 5322 官方正則極其複雜,不建議手寫)
// 實務上 filter_var 足夠,特殊需求再加強:
// 1. 禁止臨時信箱域名
// 2. 要求公司域名
// 3. 長度限制

進階:DNS 驗證(檢查域名真實存在)

<?php
function validateEmailDeep($email) {
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) return false;
    $domain = substr(strrchr($email, '@'), 1);
    // 檢查 MX 記錄
    return checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A');
}

URL 驗證

filter_var() 內建驗證

<?php
$url = trim($_POST['website'] ?? '');
if (!filter_var($url, FILTER_VALIDATE_URL)) {
    $urlErr = 'URL 格式不正確(需含 https:// 或 https://)';
}
// 選項:限制 scheme、要求路徑、查詢字串
$options = [
    'flags' => FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED,
    'options' => ['regexp' => '/^https?:\/\//i'] // 僅允許 http/https
];
// filter_var($url, FILTER_VALIDATE_URL, $options);

正則驗證(更靈活控制)

<?php
// 允許 www. 開頭、支援子域名、連接埠、路徑、查詢、錨點
$pattern = '~^
    (https?://)?                           # 選擇性 scheme
    ([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}         # 域名
    (:\d{1,5})?                            # 選擇性 port
    (/[^\s]*)?                             # 選擇性 path
    (\?[^\s#]*)?                           # 選擇性 query
    (\#[^\s]*)?                            # 選擇性 fragment
$~ix';

if (!preg_match($pattern, $url)) {
    $urlErr = 'URL 格式不正確';
}

// 自動補全 scheme
if (!preg_match('~^https?://~i', $url)) {
    $url = 'https://' . $url;
}

進階:URL 可達性檢查

<?php
function validateUrlReachable($url, $timeout = 5) {
    if (!filter_var($url, FILTER_VALIDATE_URL)) return false;
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_NOBODY => true,      // HEAD 請求
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_TIMEOUT => $timeout,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => true,
    ]);
    curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return $httpCode >= 200 && $httpCode < 400;
}

綜合驗證範例

<?php
function validateForm(array $input): array {
    $errors = [];
    $clean = [];
    
    // 姓名
    $name = trim($input['name'] ?? '');
    if ($name === '') {
        $errors['name'] = '姓名必填';
    } elseif (!preg_match('/^[\p{Han}\p{L}\s\'-]+$/u', $name)) {
        $errors['name'] = '姓名包含非法字符';
    } elseif (mb_strlen($name) > 50) {
        $errors['name'] = '姓名過長';
    } else {
        $clean['name'] = $name;
    }
    
    // Email
    $email = trim($input['email'] ?? '');
    if ($email === '') {
        $errors['email'] = 'Email 必填';
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $errors['email'] = 'Email 格式錯誤';
    } elseif (strlen($email) > 254) {
        $errors['email'] = 'Email 過長';
    } else {
        $clean['email'] = strtolower($email);
    }
    
    // 網址(選填)
    $url = trim($input['website'] ?? '');
    if ($url !== '') {
        if (!filter_var($url, FILTER_VALIDATE_URL, [
            'flags' => FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED
        ])) {
            $errors['website'] = '請輸入完整網址(含 https:// 或 https://)';
        } else {
            $clean['website'] = $url;
        }
    }
    
    return ['errors' => $errors, 'clean' => $clean];
}

// 使用
$result = validateForm($_POST);
if (empty($result['errors'])) {
    $cleanData = $result['clean'];
    // 儲存資料庫...
} else {
    // 顯示錯誤...
}
?>

常見正則模式速查

用途模式說明
手機號(台)/^09\d{8}$/09 開頭 10 碼
身分證字號/^[A-Z][12]\d{8}$/字母+性別碼+8數字
統一編號/^\d{8}$/8 位數字
郵遞區號(台)/^\d{3,5}$/3-5 碼
IPv4/^(?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d)$/標準 IPv4
十六進位顏色/^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/#RRGGBB 或 #RGB
強密碼/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/大小寫+數字+特殊符號 8+

效能與維護建議

  1. 優先使用 filter_var():內建、標準相容、無需維護正則
  2. 複雜正則加註解:使用 x 修飾符(忽略空白、允許 # 註解)
  3. 預編譯正則:靜態變數儲存,避免重複編譯
  4. 錨點 ^$:確保完整字串匹配,避免子字串誤判
  5. Unicode 支援:使用 u 修飾符、\p{L} (任意字母)、\p{Han} (漢字)
  6. 單元測試:建立驗證函數測試案例(正常、邊界、惡意輸入)

驗證不是「阻擋用戶」,而是「引導用戶輸入正確資料」。善用 PHP 內建過濾器處理標準格式,正則處理業務特定規則,並提供清晰錯誤訊息,是打造優質表單體驗的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved