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

PHP 郵箱驗證正則演進:從簡單匹配到 RFC 5322 兼容方案

     編輯:PHP 相關知識

驗證邏輯演進史

  1. 初版:^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9_-]+\.[a-z0-9_-]+.*$ —— 僅驗證用戶名,域名部分極其寬鬆,user@126,com 也能通過。
  2. 二版:^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*$ —— 修正域名結構,但未轉義點號 .,仍匹配逗號。
  3. 三版:^[_.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,3}$ —— 限制頂級域 2-3 字符,但點號仍未轉義。
  4. 四版(修正):^[_.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,4}$ —— 轉義點號,支援 4 字符頂級域(如 .info)。

推薦方案:filter_var 內置驗證(PHP 5.2+)

$email = 'test@example.com';
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo '格式合法';
} else {
    echo '格式非法';
}

優點:C 級實現、支援 IPv6 域名、國際化郵箱、自動處理邊界情況。缺點:不支援某些極其罕見的 RFC 合法地址(如帶註釋、引號字符串)。

進階:嚴格 RFC 5322 正則(PHP 實現)

function isValidEmailStrict(string $email): bool {
    // 簡化版 RFC 5322,實際生產建議使用 egulias/email-validator 庫
    $pattern = '/^
        [a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+   # local part
        @
        [a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?  # domain label
        (?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$ # more labels
    /x';
    return (bool)preg_match($pattern, $email);
}

額外驗證層級

層級方法用途
語法檢查filter_var / 正則註冊表單即時驗證
域名 MX 記錄checkdnsrr($domain, 'MX')過濾明顯虛假域名
SMTP 驗證連接郵件服務器 RCPT TO高價值業務(需異步、緩存、限流)
發送驗證碼實際投遞郵件最終確認擁有權,業界標準做法

完整註冊流程示例

function validateEmail(string $email, bool $checkMx = false): array {
    // 1. 基礎格式
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        return ['valid' => false, 'reason' => '格式不合法'];
    }

    // 2. 可選 MX 記錄檢查
    if ($checkMx) {
        $domain = substr(strrchr($email, '@'), 1);
        if (!checkdnsrr($domain, 'MX')) {
            return ['valid' => false, 'reason' => '域名無 MX 記錄'];
        }
    }

    return ['valid' => true];
}

// 使用
$result = validateEmail($_POST['email'], true);
if (!$result['valid']) {
    exit(json_encode(['code' => 400, 'msg' => $result['reason']]));
}
// 發送驗證碼郵件...

避坑指南

  • 不要過度複雜正則:維護成本高、易誤判、性能差。filter_var 覆蓋 99.9% 場景。
  • 废棄 eregi:PHP 7.0 已移除,統一用 preg_match(PCRE)。
  • 國際化郵箱:支援 Unicode 域名(IDN)需用 idn_to_ascii 轉換後再驗證。
  • 前後端一致:前端 HTML5 <input type="email"> 瀏覽器驗證規則與 PHP 不完全一致,後端必須再驗證一次。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved