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

PHP 表單驗證類別封裝:中文、Email、手機、身分證、帳號格式完整驗證

     編輯:PHP 綜合知識

類別設計目標

  • 集中管理常見表單欄位驗證規則
  • 使用正則表達式,支援參數化長度限制
  • 回傳布林值,便於控制器直接判斷
  • 錯誤訊息可擴充 (本範例簡化為靜態屬性)

完整類別原始碼

<?php
/**
 * 表單驗證類別
 * 方法回傳:true 通過,false 失敗
 */
class FormValidator {
    public static string $error = '';

    /**
     * 中文字串驗證 (僅允許中文字元)
     * @param string $str 待驗證字串
     * @param int $min 最小長度
     * @param int $max 最大長度 (0 表不限制)
     * @return bool
     */
    public function checkChinese(string $str, int $min, int $max = 0): bool {
        $max = $max ?: $min; // 若 max=0 則固定長度 = min
        $pattern = '/^[\x{4e00}-\x{9fa5}]{' . $min . ',' . $max . '}$/u';
        $result = (bool)preg_match($pattern, $str);
        if (!$result) self::$error = "中文長度需在 $min-$max 字之間";
        return $result;
    }

    /**
     * Email 格式驗證
     * @param string $email
     * @return bool
     */
    public function checkEmail(string $email): bool {
        // RFC 5322 簡化版,實務建議使用 filter_var($email, FILTER_VALIDATE_EMAIL)
        $pattern = '/^[\w\-\.]+@[\w\-]+(\.[\w\-]+)+$/';
        $result = (bool)preg_match($pattern, $email);
        if (!$result) self::$error = 'Email 格式不正確';
        return $result;
    }

    /**
     * 台灣手機號碼驗證 (09xxxxxxxx)
     * @param string $mobile
     * @return bool
     */
    public function checkMobileTW(string $mobile): bool {
        $pattern = '/^09\d{8}$/';
        $result = (bool)preg_match($pattern, $mobile);
        if (!$result) self::$error = '手機格式應為 09xxxxxxxx';
        return $result;
    }

    /**
     * 大陸手機號碼驗證 (1[3-9]xxxxxxxx)
     * @param string $mobile
     * @return bool
     */
    public function checkMobileCN(string $mobile): bool {
        $pattern = '/^1[3-9]\d{9}$/';
        $result = (bool)preg_match($pattern, $mobile);
        if (!$result) self::$error = '手機格式應為 1[3-9]xxxxxxxxx';
        return $result;
    }

    /**
     * QQ 號碼驗證 (5-11 位數字,首位非 0)
     * @param string $qq
     * @return bool
     */
    public function checkQQ(string $qq): bool {
        $pattern = '/^[1-9]\d{4,10}$/';
        $result = (bool)preg_match($pattern, $qq);
        if (!$result) self::$error = 'QQ 號碼格式不正確';
        return $result;
    }

    /**
     * 身分證字號驗證 (台灣:1 英文字母 + 9 數字)
     * @param string $id
     * @return bool
     */
    public function checkIdCardTW(string $id): bool {
        // 格式檢查
        if (!preg_match('/^[A-Z][12]\d{8}$/i', $id)) {
            self::$error = '身分證格式:1 英文字母 + 9 位數字';
            return false;
        }
        // 檢查碼驗證演算法
        $letters = 'ABCDEFGHJKLMNPQRSTUVXYWZIO'; // 實際對應表需查表
        $letter = strtoupper($id[0]);
        $num = strpos($letters, $letter);
        if ($num === false) {
            self::$error = '身分證首碼字母無效';
            return false;
        }
        $num += 10;
        $sum = (int)($num / 10) + ($num % 10) * 9;
        $weights = [8, 7, 6, 5, 4, 3, 2, 1, 1];
        for ($i = 0; $i < 9; $i++) {
            $sum += (int)$id[$i + 1] * $weights[$i];
        }
        if ($sum % 10 !== 0) {
            self::$error = '身分證檢查碼錯誤';
            return false;
        }
        return true;
    }

    /**
     * 大陸身分證 (18 位數字 或 17 位數字 + X/x)
     * @param string $id
     * @return bool
     */
    public function checkIdCardCN(string $id): bool {
        $pattern = '/^\d{17}[\dXx]$/';
        $result = (bool)preg_match($pattern, $id);
        if (!$result) self::$error = '身分證格式:18 位數字或 17 位數字+X';
        return $result; // 簡化版,未實作校驗碼演算法
    }

    /**
     * 通用帳號格式:字母/數字/底線,首字不為數字,長度限制
     * @param string $str
     * @param int $min
     * @param int $max
     * @return bool
     */
    public function checkUsername(string $str, int $min, int $max): bool {
        $pattern = '/^[a-zA-Z_]\w{' . ($min - 1) . ',' . ($max - 1) . '}$/';
        $result = (bool)preg_match($pattern, $str);
        if (!$result) self::$error = "帳號長度 $min-$max 位,首字需為字母或底線";
        return $result;
    }

    /**
     * 密碼強度驗證:至少含大小寫、數字、特殊符號,長度 8-20
     * @param string $pwd
     * @return bool
     */
    public function checkPasswordStrong(string $pwd): bool {
        $checks = [
            '/[a-z]/'   => '需含小寫字母',
            '/[A-Z]/'   => '需含大寫字母',
            '/\d/'      => '需含數字',
            '/[\W_]/'   => '需含特殊符號',
            '/^.{8,20}$/' => '長度需 8-20 位',
        ];
        foreach ($checks as $pattern => $msg) {
            if (!preg_match($pattern, $pwd)) {
                self::$error = $msg;
                return false;
            }
        }
        return true;
    }

    /**
     * 通用正則驗證
     * @param string $str
     * @param string $pattern 正則模式 (含分隔符)
     * @param string $errorMsg 失敗訊息
     * @return bool
     */
    public function checkRegex(string $str, string $pattern, string $errorMsg = '格式不符合'): bool {
        $result = (bool)preg_match($pattern, $str);
        if (!$result) self::$error = $errorMsg;
        return $result;
    }
}

使用範例

<?php
require_once 'FormValidator.php';

$validator = new FormValidator();
$_POST = [
    'username' => 'john_doe',
    'password' => 'Pass123!',
    'email'    => 'john@example.com',
    'mobile'   => '0912345678',
    'realname' => '張三',
    'idcard'   => 'A123456789',
];

$rules = [
    'username' => fn() => $validator->checkUsername($_POST['username'], 4, 16),
    'password' => fn() => $validator->checkPasswordStrong($_POST['password']),
    'email'    => fn() => $validator->checkEmail($_POST['email']),
    'mobile'   => fn() => $validator->checkMobileTW($_POST['mobile']),
    'realname' => fn() => $validator->checkChinese($_POST['realname'], 2, 10),
    'idcard'   => fn() => $validator->checkIdCardTW($_POST['idcard']),
];

$errors = [];
foreach ($rules as $field => $check) {
    if (!$check()) {
        $errors[$field] = FormValidator::$error;
    }
}

if ($errors) {
    // 回傳錯誤給前端
    echo json_encode(['success' => false, 'errors' => $errors]);
} else {
    echo json_encode(['success' => true, 'message' => '驗證通過']);
}
?>

正則表達式對照表與說明

驗證項目正則說明
中文/^[\x{4e00}-\x{9fa5}]{min,max}$/uUnicode 範圍 \x{4e00}-\x{9fa5} 涵蓋常用漢字,u 修飾符啟用 UTF-8 模式
Email/^[\w\-\.]+@[\w\-]+(\.[\w\-]+)+$/簡化版;生產環境建議 filter_var($email, FILTER_VALIDATE_EMAIL)
台灣手機/^09\d{8}$/09 開頭共 10 碼
大陸手機/^1[3-9]\d{9}$/1[3-9] 開頭共 11 碼
QQ/^[1-9]\d{4,10}$/5-11 位,首位非 0
台灣身分證/^[A-Z][12]\d{8}$/i首字母,次碼 1/2 (性別),共 10 碼;需額外檢查碼演算法
大陸身分證/^\d{17}[\dXx]$/18 位,最後一位可能為 X
帳號/^[a-zA-Z_]\w{min-1,max-1}$/首字母或底線,其後字母數字底線
強密碼多條件檢查大小寫、數字、特殊符號、長度 8-20

最佳實務建議

  1. 前後端雙重驗證:前端即時回饋 UX,後端防繞過安全。
  2. 使用 filter_var 內建驗證:Email、URL、IP、Boolean 等優先用 filter_var($val, FILTER_VALIDATE_*)。
  3. 正則效能:避免災難性回溯;長字串驗證前先檢查長度上限。
  4. 國際化支援:手機、身分證、郵遞區號等隨國家異動,建議抽離為配置或策略模式。
  5. 錯誤訊息外部化:將訊息存入語言包陣列/檔案,支援多語系。
  6. 單元測試覆蓋:每個驗證方法針對邊界值、合法/非法輸入撰寫測試案例。

擴充:策略模式重構 (支援動態規則)

interface ValidationRule {
    public function validate(string $value): bool;
    public function getError(): string;
}

class ChineseLengthRule implements ValidationRule {
    private int $min, $max; private string $error = '';
    public function __construct(int $min, int $max) { $this->min=$min; $this->max=$max; }
    public function validate(string $v): bool {
        $ok = (bool)preg_match('/^[\x{4e00}-\x{9fa5}]{'.$this->min.','.$this->max.'}$/u', $v);
        if (!$ok) $this->error = "長度需 {$this->min}-{$this->max} 字";
        return $ok;
    }
    public function getError(): string { return $this->error; }
}

// 使用
$validator = new class {
    public function validate(array $data, array $rules): array {
        $errors = [];
        foreach ($rules as $field => $rule) {
            if (!$rule->validate($data[$field] ?? '')) {
                $errors[$field] = $rule->getError();
            }
        }
        return $errors;
    }
};

$errors = $validator->validate($_POST, [
    'realname' => new ChineseLengthRule(2, 10),
    'username' => new RegexRule('/^[a-zA-Z_]\w{3,15}$/', '帳號格式錯誤'),
]);

此驗證類別涵蓋華語圈最常見表單欄位,程式碼結構清晰,易於擴充自定義規則與整合現代框架驗證元件。

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