Hàm validate số điện thoại Việt Nam chuẩn trong PHP

Số điện thoại là dữ liệu bị người dùng nhập bừa nhiều nhất: dấu cách, dấu chấm, +84 lẫn 0, đầu số cũ – mới lẫn lộn. Nếu backend không xử lý kỹ, database sẽ thành một bãi rác đúng nghĩa. Bài này tập trung vào một mục tiêu duy nhất: validate số điện thoại Việt Nam cho đúng, thực dụng và cập nhật, không đoán mò, không regex nửa mùa.

Hàm validate số điện thoại Việt Nam chuẩn trong PHP

Những sai lầm phổ biến khi validate số điện thoại

  • Chỉ kiểm tra độ dài 10 hoặc 11 số
  • Dùng regex quá đơn giản
  • Không chuẩn hóa +840
  • Không cập nhật đầu số mới
  • Bỏ qua số cố định (landline) và số máy bàn mới
  • Không kiểm tra đầu số đã bị thu hồi hay chưa

Kết quả: số rác vẫn lọt, số thật thì bị loại. Cả hai đều dở.

Định dạng số điện thoại Việt Nam hiện nay (2026)

Một số điện thoại di động Việt Nam hợp lệ có đặc điểm:

  • Bắt đầu bằng 0 hoặc +84
  • Sau khi chuẩn hóa: 10 chữ số
  • Đầu số thuộc nhà mạng hợp lệ và đang hoạt động

Ví dụ hợp lệ:

  • 0912345678
  • +84912345678
  • 0912 345 678
  • +84 912 345 678

Danh sách đầu số di động Việt Nam cập nhật 2026

Nhà mạngĐầu sốGhi chú
Viettel032039, 096099Thị phần lớn nhất, đầu số 03x là chuẩn mới
MobiFone070079, 089090, 093Đầu số 07x chuyển đổi từ 11 số (2018)
VinaPhone081088, 091094Đầu số 08x chuyển đổi từ 11 số (2018)
Vietnamobile052059Đầu số 05x chuyển đổi từ 11 số
Gmobile059Đã sáp nhập, một số đầu số chuyển nhượng
Reddi (Mobicast)055Mạng di động ảo (MVNO) mới
iTel (Indochina Telecom)087Mạng di động ảo (MVNO)
Wintel (Viettel + VNPT)092Mạng di động ảo (MVNO)

Lưu ý: Từ năm 2018, VNPT và Bộ TT&TT đã chuyển đổi toàn bộ thuê bao 11 số về 10 số. Các đầu số 012x, 016x, 018x, 019x đã ngừng hoạt động.

Chiến lược xử lý đúng

  1. Chuẩn hóa chuỗi đầu vào — loại bỏ khoảng trắng, dấu chấm, gạch ngang, ngoặc
  2. Đưa về một format thống nhất (khuyến nghị 0xxxxxxxxx)
  3. Kiểm tra chỉ chứa chữ số sau khi chuẩn hóa
  4. Kiểm tra độ dài chuẩn 10 số
  5. Kiểm tra đầu số hợp lệ theo danh sách nhà mạng cập nhật

Hàm validate số điện thoại Việt Nam (PHP — cập nhật 2026)

<?php
function validate_vietnam_phone(string $phone): bool
{
    // 1. Loại bỏ khoảng trắng, dấu chấm, dấu gạch, ngoặc
    $phone = trim($phone);
    $phone = preg_replace('/[\s\.\-\(\)]/', '', $phone);

    // 2. Chuẩn hóa +84 về 0
    if (str_starts_with($phone, '+84')) {
        $phone = '0' . substr($phone, 3);
    }

    // 3. Chỉ cho phép chữ số
    if (!ctype_digit($phone)) {
        return false;
    }

    // 4. Độ dài chuẩn (10 số)
    if (strlen($phone) !== 10) {
        return false;
    }

    // 5. Danh sách đầu số di động Việt Nam (cập nhật 2026)
    $validPrefixes = [
        // Viettel
        '032','033','034','035','036','037','038','039',
        '096','097','098','099',
        // MobiFone
        '070','076','077','078','079',
        '089','090','093',
        // VinaPhone
        '081','082','083','084','085','086','088',
        '091','092','093','094',
        // Vietnamobile
        '052','053','054','055','056','057','058','059',
        // Gmobile
        '059',
        // MVNO
        '055',  // Reddi
        '087',  // iTel
        '092',  // Wintel
    ];

    $prefix = substr($phone, 0, 3);

    return in_array($prefix, $validPrefixes, true);
}

Phiên bản JavaScript/TypeScript (Frontend)

<script>
function validateVietnamPhone(phone) {
    // 1. Chuẩn hóa
    let cleaned = phone.trim().replace(/[\s\.\-\(\)]/g, '');

    // 2. +84 → 0
    if (cleaned.startsWith('+84')) {
        cleaned = '0' + cleaned.slice(3);
    }

    // 3. Chỉ số
    if (!/^\d+$/.test(cleaned)) return false;

    // 4. Độ dài
    if (cleaned.length !== 10) return false;

    // 5. Đầu số hợp lệ (2026)
    const validPrefixes = [
        '032','033','034','035','036','037','038','039',
        '096','097','098','099',
        '070','076','077','078','079','089','090','093',
        '081','082','083','084','085','086','088','091','092','093','094',
        '052','053','054','055','056','057','058','059',
        '087'
    ];

    return validPrefixes.includes(cleaned.slice(0, 3));
}
</script>

Vì sao không dùng regex một phát cho xong

Regex có thể gộp tất cả vào một dòng, nhưng:

  • Khó đọc, khó bảo trì
  • Đầu số đổi là sửa mệt nghỉ
  • Không tái sử dụng logic chuẩn hóa cho các phần khác (format, lưu DB)
  • Khó viết unit test riêng từng bước

Tách từng bước như trên giúp:

  • Dễ debug — biết chính xác bước nào fail
  • Dễ mở rộng — thêm đầu số mới chỉ cần sửa 1 mảng
  • Dễ viết test — test từng hàm nhỏ riêng biệt
  • Không cần đọc regex mà đoán ý đồ tác giả

Ví dụ sử dụng thực tế

<?php
$phone = $_POST['phone'] ?? '';

if (!validate_vietnam_phone($phone)) {
    http_response_code(400);
    die(json_encode(['error' => 'Số điện thoại không hợp lệ']));
}

// Chuẩn hóa trước khi lưu
$normalized = normalize_vietnam_phone($phone); // trả về 0xxxxxxxxx

// An tâm lưu database
save_to_db($normalized);

Nên lưu số điện thoại theo format nào

Khuyến nghị:

  • Lưu dạng 0xxxxxxxxx — dễ đọc, dễ hiển thị, phổ biến ở VN
  • Hoặc chuẩn E.164: +84xxxxxxxxx — nếu làm hệ thống đa quốc gia, gửi SMS qua API quốc tế

Quan trọng nhất: chỉ lưu một format duy nhất. Đừng để mỗi bản ghi một kiểu. Nếu cần hiển thị đẹp, format lúc render — đừng format lúc lưu.

Bonus: Hàm chuẩn hóa + format hiển thị

<?php
function normalize_vietnam_phone(string $phone): string
{
    $phone = preg_replace('/[\s\.\-\(\)]/', '', trim($phone));
    if (str_starts_with($phone, '+84')) {
        $phone = '0' . substr($phone, 3);
    }
    return $phone;
}

function format_vietnam_phone(string $phone): string
{
    // Giả sử đã chuẩn hóa dạng 0xxxxxxxxx
    if (strlen($phone) === 10) {
        return substr($phone, 0, 4) . ' ' . substr($phone, 4, 3) . ' ' . substr($phone, 7, 3);
    }
    return $phone;
}

// Ví dụ:
// Input:  +84 912 345 678
// Normalize: 0912345678
// Format: 0912 345 678

Kết luận

Validate số điện thoại không khó, cái khó là làm cho đúng và bền. Một hàm rõ ràng, từng bước, cập nhật đầu số đầy đủ sẽ giúp backend sạch dữ liệu, frontend đỡ chửi, và bạn đỡ phải viết script dọn rác sau này.

Nhập bừa là bản năng người dùng, xử lý gọn là trách nhiệm của backend!

Bình luận


  • Không có bình luận.

Công cụ trực tuyến

Nhấn Ctrl + \ trên máy tính, hoặc vuốt sang trái ở bất kỳ đâu trên mobile.

Đăng nhập





Đang tải...