Kiểm tra và lọc dữ liệu đầu vào (validate + sanitize)

jk5587725

By jk5587725

Cập nhật Tháng 9 23, 2025

Trong một ứng dụng web, việc lấy dữ liệu từ người dùng chỉ là bước đầu tiên. Quan trọng hơn cả là kiểm tra dữ liệu đó – hay còn gọi là validating. Nếu không kiểm tra kỹ, ứng dụng có thể bị lỗi, hiển thị sai dữ liệu, hoặc tệ hơn là bị tấn công.

Trong bài học này, chúng ta sẽ tìm hiểu cách xác minh dữ liệu người dùng gửi lên thông qua form HTML. Đây là một kỹ năng cốt lõi trong mọi ứng dụng PHP thực tế.


Tại sao cần kiểm tra dữ liệu?

Người dùng (vô tình hoặc cố ý) có thể nhập:

  • Trường trống, bỏ qua yêu cầu
  • Dữ liệu sai định dạng (ví dụ: chữ thay vì số)
  • Dữ liệu độc hại (ví dụ: script HTML hay câu lệnh SQL)

Việc kiểm tra giúp:

  • Giữ dữ liệu sạch và đúng
  • Tránh lỗi hệ thống
  • Ngăn ngừa các cuộc tấn công như XSS hoặc SQL Injection

Kiểm tra dữ liệu trong PHP

Giả sử ta có một form đăng ký đơn giản:

<form method="post" action="">
  <input type="text" name="username" placeholder="Tên người dùng">
  <input type="email" name="email" placeholder="Email">
  <input type="submit" value="Đăng ký">
</form>

Ở phía PHP, ta sẽ xử lý như sau:

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
  $username = trim($_POST["username"]);
  $email = trim($_POST["email"]);

  $errors = [];

  if (empty($username)) {
    $errors[] = "Vui lòng nhập tên người dùng.";
  }

  if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $errors[] = "Email không hợp lệ.";
  }

  if (empty($errors)) {
    echo "Dữ liệu hợp lệ. Tiến hành lưu vào hệ thống.";
  } else {
    foreach ($errors as $err) {
      echo "<p>$err</p>";
    }
  }
}
?>

Một số hàm và kỹ thuật phổ biến

  • trim() – loại bỏ khoảng trắng đầu/cuối
  • htmlspecialchars() – chuyển ký tự đặc biệt để chống XSS
  • filter_var() – kiểm tra và lọc dữ liệu (rất hữu ích)

Ví dụ kiểm tra số điện thoại:

$phone = $_POST['phone'];
if (!preg_match('/^[0-9]{10,11}$/', $phone)) {
  echo "Số điện thoại không hợp lệ.";
}

Làm sạch dữ liệu (Sanitize): Bức tường phòng thủ đầu tiên

Việc xác thực (validate) dữ liệu giúp đảm bảo rằng người dùng nhập đúng định dạng (ví dụ: email đúng cấu trúc, số điện thoại không chứa chữ cái…), nhưng sanitize (làm sạch) dữ liệu mới là công đoạn giảm thiểu rủi ro tấn công như XSS (Cross-site Scripting) hoặc SQL Injection.

Hãy tưởng tượng: bạn mở một quán ăn nhỏ, validate là bạn xem khách có đặt đúng món trong menu không, còn sanitize là bạn… lau sạch cái muỗng trước khi đưa khách dùng. Cả hai đều cần thiết nếu bạn không muốn bị “review 1 sao”.

Kỹ thuật sanitize (làm sạch dữ liệu) — một bước rất quan trọng trong bảo mật ứng dụng web PHP.

Một vài hàm sanitize quen thuộc

PHP cung cấp khá nhiều công cụ để làm sạch dữ liệu. Dưới đây là một số cách phổ biến:

$name = trim($_POST['name']); // bỏ khoảng trắng đầu cuối
$name = htmlspecialchars($name); // chuyển ký tự đặc biệt thành dạng an toàn HTML
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL); // loại ký tự không hợp lệ với email
$url = filter_var($_POST['website'], FILTER_SANITIZE_URL); // làm sạch URL

Tại sao phải làm vậy?

  • Người dùng có thể nhập <script>alert('hack');</script> vào ô tên – và nếu bạn hiển thị lại giá trị đó mà không xử lý, trang của bạn có thể bị tấn công XSS ngay lập tức.
  • Một số trình duyệt cũ còn… ngây thơ, sẽ chạy đoạn script nếu bạn không mã hóa các ký tự đặc biệt (<, >, &, ", '…).

Gợi ý cách viết lại đoạn xử lý form an toàn hơn

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $name = trim($_POST['name']);
    $name = htmlspecialchars($name);

    $email = filter_var(trim($_POST['email']), FILTER_SANITIZE_EMAIL);
    $message = htmlspecialchars(trim($_POST['message']));
    
    // Sau đó mới validate nếu cần
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        echo "Email không hợp lệ!";
    } else {
        echo "Cảm ơn bạn, " . $name . ". Chúng tôi đã nhận được tin nhắn!";
    }
}

Khi nào sanitize, khi nào validate?

  • Validate: Khi bạn cần kiểm tra dữ liệu có đúng định dạng hoặc logic không (ví dụ: ngày sinh không được lớn hơn hôm nay).
  • Sanitize: Khi bạn muốn làm sạch trước khi lưu dữ liệu hoặc hiển thị lại lên giao diện.

Cách đơn giản để nhớ:
Validate để từ chối dữ liệu sai → Sanitize để bảo vệ ứng dụng khỏi dữ liệu nguy hiểm.


Ghi chú nhỏ

Nhiều dev mới chỉ dùng htmlspecialchars() là tưởng “an toàn tuyệt đối”, nhưng thực ra bạn nên kết hợp thêm các bước như filter_var(), và hiểu rõ dữ liệu sẽ được dùng ở đâu (hiển thị lại, ghi vào DB, dùng trong URL…) để chọn phương pháp xử lý phù hợp.


Lưu ý

  • Kiểm tra phía PHP là bắt buộc, kể cả khi có JavaScript kiểm tra phía client.
  • Không bao giờ tin tưởng dữ liệu người dùng gửi lên.
  • Đặt thêm layer kiểm tra bảo mật khi dữ liệu quan trọng.

Bài tập áp dụng

  1. Tạo một form liên hệ gồm tên, email, nội dung. Sau khi submit, kiểm tra:
    • Tên không rỗng
    • Email hợp lệ
    • Nội dung dài hơn 10 ký tự
  2. Hiển thị lỗi tương ứng nếu có, và giữ lại giá trị cũ đã nhập nếu có lỗi.

Gợi ý học thêm

  • HTML & Form cơ bản – nếu bạn còn lúng túng với <form>, <input>, bạn nên học thêm HTML.
  • Regex (Biểu thức chính quy) – cực kỳ hữu dụng khi kiểm tra định dạng dữ liệu.

Thảo luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Đăng ký nhận tin mới

Nhận bài học, tài nguyên và cơ hội việc làm qua email hàng tuần.

[global_subscribe_form]

Chúng tôi cam kết không spam. Bạn có thể hủy bất cứ lúc nào.