Thứ Sáu, 9 tháng 5, 2025

18.Form Validation - Kiểm tra tính hợp lệ của Form trong PHP phần 4

Phần này chúng ta thảo luận về Validate URL. Có những khái niệm tương đối "khó nhằn", nhưng chúng ta sẽ cố gắng "đào sâu".

Nhìn qua một số URL chúng ta sẽ thấy sự đa dạng, dài ngắn...đủ kiểu. Tựu trung lại bao gồm:

  1. Tên, ví dụ DatVietLapTrinh
  2. Dấu chấm  '.'
  3. Phần mở rộng, ví dụ COM, NET, US....


Tạm gác lại "hình dáng" của các URL, chúng ta tìm hiểu một thứ tương đối "loằng ngoằng" đó là Regular Expressions.

PCRE (Perl Compatible Regular Expressions) là một thư viện mã nguồn mở mạnh mẽ, dùng để khớp các mẫu văn bản (pattern matching) theo cú pháp và ngữ nghĩa của ngôn ngữ Perl. Đây là chuẩn Regex phổ biến nhất, được sử dụng rộng rãi trong các ngôn ngữ lập trình như PHP (hàm preg_*), Apache, và nhiều công cụ khác nhờ tính linh hoạt cao


Cú pháp Regex PCRE Cơ bản

PCRE sử dụng các ký tự đặc biệt để tạo khuôn mẫu tìm kiếm:

-Ký tự đại diện: . khớp với bất kỳ ký tự nào ngoại trừ dòng mới (newline).


-Neo (Anchors): ^ khớp đầu dòng, $ khớp cuối dòng.


-Lượng từ (Quantifiers):

  • *: 0 hoặc nhiều lần.
  • +: 1 hoặc nhiều lần.
  • ?: 0 hoặc 1 lần (không bắt buộc).


-Nhóm và thay thế:

  • (): Nhóm các ký tự.
  • |: Toán tử OR (hoặc).


-Ký tự đặc biệt (Escaping): Dùng \ trước các ký tự đặc biệt để tìm chính nó, ví dụ \. để tìm dấu chấm


PCRE được sử dụng chủ yếu thông qua các hàm preg_ trong PHP:

  • preg_match(): Kiểm tra xem mẫu có khớp trong chuỗi không.
  • preg_match_all(): Tìm tất cả các kết quả khớp.
  • preg_replace(): Tìm và thay thế nội dung dựa trên pattern. 



Các mẫu PCRE thường dùng

`\d+`: Khớp với một hoặc nhiều chữ số (ví dụ: "123").

`\s+`: Khớp với một hoặc nhiều khoảng trắng, ký tự tab, hoặc ký tự xuống dòng.

`[a-z]{3}`: Khớp chính xác ba chữ cái thường.

`^Start`: Chỉ khớp với từ "Start" khi nó nằm ở đầu của một chuỗi.

\b: Ranh giới từ (đảm bảo rằng mẫu khớp với toàn bộ một từ, chứ không phải một phần của từ dài hơn).

[A-Z]: Khớp với một chữ cái in hoa. chữ cái.

[a-z]+: Khớp với một hoặc nhiều chữ cái thường.

\w+ : Khớp với chữ cái/chữ số/dấu gạch dưới. 


Vài ví dụ:

^\d{5}$ : Ý nghĩa: Tìm những chuỗi có 5 chữ số. Những dãy 5 chữ số sẽ khớp, ví dụ "85261" hay "65378". Nhưng "2354" lại không khớp.

\b[A-Z][a-z]+\b: Ý nghĩa: Tìm những chuỗi Mở đầu bằng một chữ hoa, theo sau là 1 hoặc nhiều chữ cái thường. Nếu một chuỗi "Hello world, welcome to Pcre." thì "Hello" và "Pcre" sẽ khớp .

[\w.-]+@[\w.-]+\.\w+ :Ý nghĩa: Tìm chuỗi bao gồm mở đầu là một hoạc vài chữ cái/chữ số tiếp theo là một hoặc vài bất cứ ký tự nào ngoài trừ newline. Tiếp theo là dấu @. Sau đó là chuỗi bao gồm mở đầu là một hoạc vài chữ cái/chữ số tiếp theo là một hoặc vài bất cứ ký tự nào ngoài trừ newline. Tiếp theo là dấu chấm ".". Cuối cùng là chuỗi bao gồm mở đầu là một hoạc vài chữ cái/chữ số tiếp theo là một hoặc vài bất cứ ký tự nào ngoài trừ newline. Nói chung là một dạng đơn giản của EMAIL.


Bây giờ quay lại URL. Dựa vào "mớ" kiến thức "loằng ngoằng" trên, chúng ta sẽ thêm code kiểm tra như sau:

// Kiểm tra URL có hợp lệ không

    if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i",$website)) {

      $websiteerr = "Định dạng website không hợp lệ";

    }


Đồng thời sẽ in ra thông báo:


<span class="error"> <?php echo $websiteerr ;?></span>


Đây là thành quả nghiên cứu của chúng ta: Nó không hoàn thiện vì khi xét biến rỗng websiteerr ban đầu, nó cũng báo không hợp lệ. Nhưng về mặt kiểm tra "tư cách" thì nó hoạt động hoàn hảo.

<html>

<head>

<style>

     .error {color: #FF0000;}

</style>

</head>

<body>  


<?php


// define variables and set to empty values

$ten = $email = $gioitinh = $ghichu = $website = "";

$tenerr = $emailerr = $gioitinherr = $ghichuerr= $websiteerr = "";


if ($_SERVER["REQUEST_METHOD"] == "POST") {

 if (empty($_POST["ten"])) {

     $tenerr = "Bạn phải nhập họ tên";

 }

 else

 {

     $ten = test_input($_POST["ten"]);

 }

   if (empty($_POST["email"])) {

     $emailerr = "Bạn phải nhập địa chỉ Email";

  }

  else

  {

      $email = test_input($_POST["email"]);

      // kiểm tra đã nhập đúng định dạng email chưa

      if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {

         $emailerr = "Định dạng Email không hợp lệ"; 

      }

   }


  $website = test_input($_POST["website"]);

  // Kiểm tra URL có hợp lệ không

    if (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i",$website)) {

      $websiteerr = "Định dạng website không hợp lệ";

    }

  $ghichu = test_input($_POST["ghichu"]);

  $gioitinh = test_input($_POST["gioitinh"]);


}


function test_input($data) {

  $data = trim($data);

  $data = stripslashes($data);

  $data = htmlspecialchars($data);

  return $data;

}

?>


<h2>Ví Dụ PHP Form Validation </h2>


<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">  

  Tên: <input type="text" name="ten"> <span class="error">* <?php echo $tenerr;?></span>

  <br><br>

  E-mail: <input type="text" name="email"> <span class="error">* <?php echo $emailerr;?></span>

  <br><br>

  Website: <input type="text" name="website"> <span class="error"> <?php echo $websiteerr ;?></span>

  <br><br>

  Ghi Chú: <textarea name="ghichu" rows="5" cols="40"></textarea>

  <br><br>


  Giới tính:

  <input type="radio" name="gioitinh" value="nữ">Nữ

  <input type="radio" name="gioitinh" value="nam">Nam

  <br><br>


  <input type="submit" name="submit" value="Submit">  

</form>

<?php


echo "<h2>Bạn đã điền thông tin:</h2>";

echo $ten;

echo "<br>";

echo $email;

echo "<br>";

echo $website;

echo "<br>";

echo $ghichu;

echo "<br>";

echo $gioitinh;


?>

</body>

</html>


Chạy thử