# **I. PHP là gì?**
PHP (Hypertext Preprocessor) là một ngôn ngữ lập trình mã nguồn mở thường được sử dụng để phát triển ứng dụng web.
## ***Nguyên lý hoạt động:***
* PHP thường được tích hợp trực tiếp vào mã HTML để tạo nên các trang web động.
* Mã PHP được chèn vào giữa các thẻ <?php và ?>.
* File được lưu với đuôi mở rộng là ***.php***
```html
<!DOCTYPE html>
<html>
<head>
<title>Ví dụ về PHP trong HTML</title>
</head>
<body>
<h1>Chào mừng đến với trang web của tôi</h1>
<?php
echo "<p>Đây là một đoạn văn bản được tạo ra bởi PHP!</p>";
?>
<p>Đây là một đoạn văn bản HTML thông thường.</p>
<?php
$ngayHienTai = date('d/m/Y');
echo "<p>Hôm nay là ngày: $ngayHienTai</p>";
?>
</body>
</html>
```
---
# II. Kiểu dữ liệu trong PHP
PHP là một ngôn ngữ lập trình yếu kiểu (loosely typed), nghĩa là bạn không cần phải khai báo kiểu dữ liệu của biến trước khi sử dụng chúng. PHP tự động chuyển đổi kiểu dữ liệu dựa trên bối cảnh mà biến được sử dụng. Dưới đây là các kiểu dữ liệu cơ bản trong PHP:
## *1. Kiểu Boolean*
Đại diện cho hai giá trị true hoặc false. Thường được sử dụng trong điều kiện và vòng lặp.
## *2. Kiểu Integer*
Đại diện cho các số nguyên không có phần thập phân. Ví dụ: 123, -123.
## *3. Kiểu Float / Double*
Đại diện cho các số thực, bao gồm cả số có phần thập phân. Ví dụ: 10.5, -0.1.
## *4. Kiểu String*
Đại diện cho chuỗi ký tự. Có thể được khai báo bằng cách sử dụng dấu nháy đơn (') hoặc dấu nháy kép ("). Ví dụ: 'hello', "world".
## *5. Kiểu Array*
Đại diện cho một tập hợp có thứ tự của các giá trị (có thể là các kiểu dữ liệu khác nhau). Các giá trị trong mảng có thể được truy cập thông qua chỉ số hoặc khóa.
## *6. Kiểu Object*
Đại diện cho một thực thể có các thuộc tính và phương thức. Đối tượng được tạo từ các lớp.
## *7. Kiểu Resource*
Đại diện cho một tài nguyên đặc biệt được giữ bởi PHP, thường liên quan đến tài nguyên ngoại vi như là file, kết nối cơ sở dữ liệu, v.v.
## *8. Kiểu NULL*
Đại diện cho một biến không có giá trị. Một biến được coi là NULL nếu nó chưa được gán giá trị hoặc đã được gán giá trị null.
## *9. Kiểu Mixed*
Không phải là một kiểu dữ liệu thực sự trong PHP, nhưng được sử dụng trong tài liệu để chỉ ra rằng một hàm có thể chấp nhận nhiều kiểu dữ liệu khác nhau.
## *10. Kiểu Callable*
Cũng không phải là một kiểu dữ liệu thực sự, nhưng được dùng để chỉ một tham chiếu đến một hàm có thể được gọi.
---
# III. Các hàm có sẵn trong PHP
PHP cung cấp một bộ sưu tập lớn các hàm được xây dựng sẵn (built-in functions) để thực hiện nhiều tác vụ khác nhau. Các hàm này được tổ chức thành các nhóm dựa trên chức năng hoặc loại tác vụ mà chúng hỗ trợ. Dưới đây là một số nhóm hàm nổi bật trong PHP:
### 1. Xử Lý Chuỗi (String Functions)
- Các hàm xử lý và thao tác chuỗi, như `strlen()`, `str_replace()`, `strpos()`, `strtolower()`, `strtoupper()`, v.v.
### 2. Xử Lý Mảng (Array Functions)
- Các hàm liên quan đến mảng, như `array_merge()`, `array_push()`, `array_keys()`, `sort()`, `count()`, v.v.
### 3. Xử Lý File và Thư Mục (File System Functions)
- Các hàm để làm việc với file và thư mục, như `fopen()`, `fclose()`, `file_get_contents()`, `file_put_contents()`, `is_file()`, v.v.
### 4. Xử Lý Ngày Tháng (Date and Time Functions)
- Các hàm liên quan đến ngày và giờ, như `date()`, `time()`, `strtotime()`, `mktime()`, v.v.
### 5. Xử Lý Cơ Sở Dữ Liệu (Database Functions)
- Các hàm để tương tác với cơ sở dữ liệu, đặc biệt là với MySQL (ví dụ, `mysqli_*` functions) và PDO.
### 6. Hàm Toán Học (Math Functions)
- Các hàm toán học như `rand()`, `max()`, `min()`, `round()`, `abs()`, v.v.
### 7. Xử Lý JSON (JSON Functions)
- Các hàm liên quan đến mã hóa và giải mã JSON, như `json_encode()` và `json_decode()`.
### 8. Xử Lý XML (XML Functions)
- Các hàm để xử lý dữ liệu XML, như các hàm trong mở rộng SimpleXML và DOM.
### 9. Xử Lý Session (Session Functions)
- Các hàm quản lý session, như `session_start()`, `session_destroy()`, `session_id()`, v.v.
### 10. Xử Lý Hình Ảnh (Image Processing and Generation)
- Các hàm liên quan đến xử lý hình ảnh, thường sử dụng thư viện GD hoặc Imagick.
### 11. Xử Lý Lỗi và Ngoại Lệ (Error Handling and Logging)
- Các hàm liên quan đến xử lý lỗi và ghi log, như `error_reporting()`, `set_error_handler()`, `trigger_error()`, v.v.
### 12. Các Hàm Bảo Mật (Security Functions)
- Các hàm liên quan đến mã hóa, băm và bảo mật, như `password_hash()`, `openssl_encrypt()`, v.v.
### 13. Các Hàm Lọc và Kiểm Tra (Filter and Validation Functions)
- Các hàm để lọc và kiểm tra dữ liệu, như `filter_var()`, `filter_input()`, v.v.
---
# **IV. Mảng trong PHP**
Mảng (array) là một cấu trúc dữ liệu phức tạp cho phép bạn lưu trữ và quản lý nhiều giá trị dưới một tên biến duy nhất. Mảng có thể chứa các giá trị của bất kỳ kiểu dữ liệu nào và kích thước của nó có thể thay đổi động.
## 1. ***Các loại mảng trong PHP***
*Mảng Tuần Tự (Indexed Arrays):*
Các giá trị được lưu trữ với chỉ mục số (bắt đầu từ 0).
Ví dụ:
```php
$colors = array("red", "green", "blue");
```
*Mảng Kết Hợp (Associative Arrays):*
Các giá trị được lưu trữ với các khóa được định nghĩa bởi người dùng (thường là chuỗi).
Ví dụ:
```php
$age = array("Peter" => 35, "Ben" => 37, "Joe" => 43);
```
*Mảng Đa Chiều (Multidimensional Arrays):*
Mảng chứa một hoặc nhiều mảng khác như là các giá trị của nó.
Ví dụ:
```php
$students = [
['name' => 'Nguyen Van A', 'gender' => 'male'],
['name' => 'Le Thi Hoa', 'gender' => 'female'],
];
// Or
$students = [
'student_1' => ['name' => 'Nguyen Van A', 'gender' => 'male'],
'student_2' => ['name' => 'Le Thi Hoa', 'gender' => 'female'],
];
```
## 2. ***Thao tác cơ bản với mảng***
*Tạo Mảng:*
```php
$array = array("value1", "value2", "value3");
// Hoặc sử dụng cú pháp ngắn gọn
$array = ["value1", "value2", "value3"];
```
*Truy Cập Phần Tử Mảng:*
```php
echo $array[0]; // In ra "value1"
```
*Thêm Phần Tử:*
```php
$array[] = "value4"; // Thêm vào cuối mảng
```
*Đếm Số Phần Tử:*
```php
count($array);
```
*Duyệt Mảng - Sử dụng vòng lặp foreach:*
```php
foreach ($array as $value) {
echo $value;
}
```
*Xóa Phần Tử:*
```php
unset($array[2]); // Xóa phần tử với chỉ mục 2
```
*Sắp Xếp Mảng:*
Sử dụng các hàm như sort(), asort(), ksort(), v.v. để sắp xếp mảng theo giá trị hoặc khóa.
Một số Hàm Mảng Phổ Biến:
array_merge(): Gộp hai hoặc nhiều mảng.
array_slice(): Trích xuất một phần của mảng.
array_push(): Thêm một hoặc nhiều phần tử vào cuối mảng.
array_keys(): Trả về tất cả các khóa của mảng.
in_array(): Kiểm tra một giá trị có tồn tại trong mảng hay không.
## 3. Hàm array_map()
`array_map()` là một hàm trong PHP được sử dụng để áp dụng một hàm callback cho mỗi phần tử của một hoặc nhiều mảng. Hàm này trả về một mảng mới, với mỗi phần tử là kết quả của việc áp dụng hàm callback lên phần tử tương ứng của mảng đầu vào.
### Cú Pháp:
```php
array_map(callable $callback, array $array1, array $array2, ...)
```
- **$callback**: Hàm callback để áp dụng cho mỗi phần tử của mảng.
- **$array1, $array2, ...**: Một hoặc nhiều mảng để áp dụng hàm callback.
### Ví Dụ:
1. **Áp Dụng Hàm Lên Mỗi Phần Tử của Một Mảng:**
```php
function square($num) {
return $num * $num;
}
$numbers = [1, 2, 3, 4, 5];
$squared = array_map('square', $numbers);
print_r($squared); // In ra [1, 4, 9, 16, 25]
```
2. **Sử Dụng Hàm Ẩn Danh (Anonymous Function):**
```php
$numbers = [1, 2, 3, 4, 5];
$squared = array_map( function($num) {
return $num * $num;
}, $numbers );
print_r($squared); // In ra [1, 4, 9, 16, 25]
```
3. **Áp Dụng Hàm Cho Nhiều Mảng:**
```php
$a = [1, 2, 3];
$b = [4, 5, 6];
$sum = array_map( function($num1, $num2) {
return $num1 + $num2;
}, $a, $b);
print_r($sum); // In ra [5, 7, 9]
```
### Lưu Ý:
- Nếu các mảng truyền vào `array_map()` có số phần tử khác nhau, mảng ngắn hơn sẽ được bổ sung giá trị `null` cho đến khi đủ số phần tử tương ứng với mảng dài nhất.
- Hàm `array_map()` rất hữu ích khi cần xử lý dữ liệu của mảng mà không cần viết vòng lặp. Nó giúp mã nguồn gọn gàng hơn và dễ đọc hơn.
## 4. Hàm array_filter()
`array_filter()` là một hàm trong PHP được sử dụng để lọc các phần tử của một mảng sử dụng một hàm callback. Hàm này trả về một mảng mới chứa tất cả các phần tử của mảng đầu vào mà hàm callback trả về `true`.
### Cú Pháp:
```php
array_filter(array $array, callable $callback = ?, int $flag = 0)
```
- **$array**: Mảng đầu vào cần lọc.
- **$callback**: Hàm callback để kiểm tra mỗi phần tử của mảng. Nếu hàm callback không được cung cấp, các phần tử sẽ được lọc dựa trên giá trị của chúng (giá trị `false`, `null`, `0`, và chuỗi rỗng `""` sẽ bị loại bỏ).
- **$flag**: Cờ tùy chọn có thể thay đổi hành vi của hàm.
### Ví Dụ:
1. **Lọc Mảng Không Sử Dụng Hàm Callback:**
```php
$numbers = [0, 1, 2, 3, 4, 5, "", null, false];
$filtered = array_filter($numbers);
print_r($filtered); // In ra các phần tử khác 0, "", null, false
```
2. **Sử Dụng Hàm Callback Để Lọc:**
```php
function odd($var) {
// Trả về true nếu $var là số lẻ
return ($var % 2 == 1);
}
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
$odd = array_filter($numbers, "odd");
print_r($odd); // In ra các số lẻ
```
3. **Sử Dụng Hàm Ẩn Danh (Anonymous Function):**
```php
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
$even = array_filter($numbers, function($num) {
return $num % 2 == 0;
});
print_r($even); // In ra các số chẵn
```
### Lưu Ý:
- Mảng trả về bởi `array_filter()` sẽ giữ nguyên khóa của các phần tử. Nếu bạn muốn khóa được đánh số lại từ 0, có thể sử dụng hàm `array_values()` trên kết quả.
- `array_filter()` là một cách hiệu quả để loại bỏ các phần tử không mong muốn khỏi mảng hoặc để thực hiện các biến đổi dựa trên điều kiện cụ thể.
---
# V. Cách tạo hàm trong PHP
Trong PHP, việc viết một hàm (function) là cách cơ bản để đóng gói một đoạn mã để có thể sử dụng lại nhiều lần. Dưới đây là cú pháp cơ bản và một số ví dụ về cách viết hàm trong PHP.
### Cú Pháp Cơ Bản:
```php
function functionName($parameter1, $parameter2, ...) {
// Code to be executed
return $result; // Optional
}
```
- `function`: Từ khóa để khai báo hàm.
- `functionName`: Tên của hàm.
- `$parameter1, $parameter2, ...`: Các tham số truyền vào hàm (tùy chọn).
- Trong phần thân hàm, bạn viết code thực hiện công việc mong muốn.
- `return $result;`: Trả về giá trị (không bắt buộc). Nếu hàm không trả về giá trị, `return` có thể bị bỏ qua.
### Ví Dụ:
1. **Hàm Không Có Tham Số:**
```php
function sayHello() {
echo "Hello World!";
}
sayHello(); // Gọi hàm
```
2. **Hàm Có Tham Số:**
```php
function add($number1, $number2) {
return $number1 + $number2;
}
echo add(5, 10); // In ra 15
```
3. **Hàm Với Tham Số Mặc Định:**
```php
function greet($name = "World") {
echo "Hello, $name!";
}
greet("John"); // In ra "Hello, John!"
greet(); // In ra "Hello, World!" vì không có tham số được truyền vào
```
4. **Hàm Ẩn Danh (Anonymous Function):**
```php
$multiply = function($a, $b) {
return $a * $b;
};
echo $multiply(3, 4); // In ra 12
```
### Lưu Ý:
- Tên hàm **không phân biệt hoa thường** (case-insensitive).
- Hàm trong PHP nên được đặt tên sao cho phản ánh rõ ràng chức năng của nó.
- Tránh đặt tên trùng lặp với tên hàm có sẵn trong PHP.
---
# VI. Xử lý dữ liệu date/time trong PHP
Trong PHP, không có kiểu dữ liệu cụ thể được gọi là "date" như trong một số ngôn ngữ lập trình khác. Thay vào đó, PHP xử lý ngày và thời gian thông qua chuỗi (string) và timestamp (dấu ấn thời gian), cũng như thông qua các lớp đối tượng như `DateTime` và `DateTimeImmutable`.
### Timestamp:
Timestamp là một biểu diễn số nguyên của một thời điểm, định nghĩa là số giây tính từ thời điểm đó tới điểm bắt đầu của thời đại Unix (00:00:00 UTC, ngày 1 tháng 1 năm 1970).
- Dùng hàm `time()` để lấy timestamp hiện tại.
- Chuyển đổi timestamp sang định dạng ngày/giờ dùng hàm `date()`.
### Lớp `DateTime`:
Lớp `DateTime` cung cấp các phương thức để làm việc với ngày và thời gian.
- Tạo đối tượng `DateTime`:
```php
$date = new DateTime(); // Ngày và giờ hiện tại
$specificDate = new DateTime('2023-01-01 10:00:00'); // Một thời điểm cụ thể
```
- Định dạng ngày và thời gian:
```php
echo $date->format('Y-m-d H:i:s');
```
### Lớp `DateTimeImmutable`:
`DateTimeImmutable` tương tự như `DateTime` nhưng bất biến (immutable). Mọi sửa đổi đối với đối tượng `DateTimeImmutable` sẽ tạo ra một đối tượng mới thay vì thay đổi đối tượng hiện tại.
### Chức Năng Xử Lý Ngày Tháng:
PHP cung cấp nhiều hàm để xử lý ngày và thời gian, như `strtotime()`, `mktime()`, `checkdate()`, v.v.
### Ví Dụ:
```php
echo date('Y-m-d'); // In ra ngày hiện tại
// Tạo đối tượng DateTime
$date = new DateTime();
echo $date->format('Y-m-d H:i:s');
// Tính toán ngày trong tương lai
$interval = new DateInterval('P10D'); // 10 ngày
$date->add($interval);
echo $date->format('Y-m-d H:i:s');
```
## Một số hàm thường dùng để xử lý dữ liệu date/time
### 1. `date()`
- **Mô tả:** Định dạng một dấu thời gian UNIX thành ngày và thời gian.
- **Ví dụ:** `echo date("Y-m-d H:i:s");`
### 2. `time()`
- **Mô tả:** Lấy dấu thời gian UNIX hiện tại.
- **Ví dụ:** `$now = time();`
### 3. `mktime()`
- **Mô tả:** Tạo một dấu thời gian UNIX từ các thành phần như giờ, phút, giây, tháng, ngày, năm.
- **Ví dụ:** `$time = mktime(0, 0, 0, 1, 1, 2020);`
### 4. `strtotime()`
- **Mô tả:** Chuyển đổi bất kỳ chuỗi ngày tháng tiếng Anh thành dấu thời gian UNIX.
- **Ví dụ:** `$tomorrow = strtotime("tomorrow");`
### 5. `checkdate()`
- **Mô tả:** Kiểm tra xem ngày, tháng, năm có phải là một ngày hợp lệ hay không.
- **Ví dụ:** `checkdate(12, 31, 2020);`
### 6. `getdate()`
- **Mô tả:** Lấy thông tin ngày tháng từ dấu thời gian UNIX.
- **Ví dụ:** `$dateInfo = getdate(time());`
### 7. `date_create()`
- **Mô tả:** Tạo một đối tượng `DateTime`.
- **Ví dụ:** `$date = date_create("2023-01-01");`
### 8. `date_modify()`
- **Mô tả:** Thay đổi đối tượng `DateTime`.
- **Ví dụ:** `date_modify($date, "+1 day");`
### 9. `date_format()`
- **Mô tả:** Định dạng đối tượng `DateTime`.
- **Ví dụ:** `echo date_format($date, "Y-m-d");`
### 10. `date_diff()`
- **Mô tả:** Tính toán sự khác biệt giữa hai ngày.
- **Ví dụ:** `$interval = date_diff($date1, $date2);`
### 11. `date_add()`
- **Mô tả:** Thêm một khoảng thời gian định nghĩa bởi `DateInterval` vào đối tượng `DateTime`.
- **Ví dụ:** `date_add($date, date_interval_create_from_date_string("10 days"));`
### 12. `date_sub()`
- **Mô tả:** Trừ một khoảng thời gian từ một đối tượng `DateTime`.
- **Ví dụ:** `date_sub($date, date_interval_create_from_date_string("10 days"));`
### Lưu Ý:
- Khi làm việc với các hàm liên quan đến ngày và thời gian, hãy lưu ý về múi giờ (`timezone`) và cách chúng ảnh hưởng đến việc xử lý ngày/thời gian. Múi giờ có thể được thiết lập toàn cục trong cấu hình PHP hoặc cục bộ trong script.
- Lớp `DateTime` và `DateTimeImmutable` cung cấp phương thức linh hoạt và mạnh mẽ để xử lý ngày và thời gian, khuyến khích sử dụng chúng thay vì hàm `date()` và `time()` trong các ứng dụng phức tạp.
---
# VII. Cách tạo HTML Form để người dùng nhập dữ liệu
## 1. Cách tạo form
### Bước 1: Tạo HTML Form
HTML form là nơi người dùng nhập dữ liệu. Có thể gửi dữ liệu này đến server thông qua phương thức `GET` hoặc `POST`.
```html
<form action="submit.php" method="post">
<label for="name">Tên:</label>
<input type="text" id="name" name="name"><br><br>
<label for="email">Email:</label>
<input type="email" id="email" name="email"><br><br>
<input type="submit" value="Gửi">
</form>
```
Trong ví dụ trên, dữ liệu sẽ được gửi đến file `submit.php` thông qua phương thức `POST`.
### Bước 2: Xử Lý Dữ Liệu với PHP
Trong file `submit.php`, bạn sẽ xử lý dữ liệu được gửi từ form. Sử dụng biến toàn cục `$_POST` để truy cập dữ liệu.
```php
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Lấy dữ liệu từ form
$name = $_POST['name'];
$email = $_POST['email'];
// Xử lý dữ liệu: Ví dụ, lưu vào database, gửi email, v.v.
echo "Tên: " . $name . "<br>";
echo "Email: " . $email;
}
?>
```
### Tích Hợp Trong Cùng Một File
Bạn cũng có thể tích hợp form và xử lý dữ liệu trong cùng một file PHP.
```php
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Xử lý dữ liệu ở đây
}
?>
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post">
<!-- Phần tử form -->
</form>
```
Trong trường hợp này, dữ liệu form sẽ được gửi đến cùng một file. Hàm `htmlspecialchars($_SERVER["PHP_SELF"])` đảm bảo rằng form gửi dữ liệu đến chính file hiện tại một cách an toàn.
## 2. Sự khác biệt giữa phương thức GET và POST
Phương thức `GET` và `POST` là hai phương thức phổ biến được sử dụng trong việc gửi dữ liệu từ form HTML đến máy chủ (server). Mỗi phương thức có những đặc điểm và ứng dụng riêng biệt. Dưới đây là sự khác biệt chính giữa chúng:
### GET
1. **Dữ liệu trong URL:** Dữ liệu được gửi qua URL.
2. **Hạn chế Dữ Liệu:** Có giới hạn về số lượng và kích thước dữ liệu có thể gửi.
3. **Bảo Mật:** Ít bảo mật hơn, vì dữ liệu hiển thị trên URL. Không nên sử dụng cho thông tin nhạy cảm.
4. **Lưu Trữ và Chia Sẻ:** Có thể lưu URL vào bookmark và chia sẻ dễ dàng.
5. **Idempotent:** Là phương thức idempotent, nghĩa là việc thực hiện nhiều lần liên tiếp có kết quả như nhau.
6. **Sử Dụng:** Thường được sử dụng cho việc truy vấn dữ liệu, như tìm kiếm.
### POST
1. **Dữ liệu trong Body của Request:** Dữ liệu được gửi qua phần body của HTTP request.
2. **Hạn chế Dữ Liệu:** Không giới hạn (hoặc giới hạn rất cao) về kích thước dữ liệu gửi.
3. **Bảo Mật:** An toàn hơn, vì dữ liệu không hiển thị trên URL.
4. **Lưu Trữ và Chia Sẻ:** Không thể lưu vào bookmark và khó chia sẻ hơn.
5. **Idempotent:** Không phải là phương thức idempotent, có thể gây ra thay đổi mỗi khi thực hiện.
6. **Sử Dụng:** Thường được sử dụng cho việc gửi dữ liệu nhạy cảm hoặc lớn, như form đăng ký.
## 3. Ví dụ về một cách tạo form điển hình
### Bước 1: Tạo `form.php`
```php
<?php
function clean_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
// Khởi tạo biến để lưu giá trị form và thông báo lỗi
$name = $email = "";
$nameErr = $emailErr = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Validate tên
if (empty($_POST["name"])) {
$nameErr = "Tên không được để trống";
} else {
$name = clean_input($_POST["name"]);
// Kiểm tra tên chỉ chứa chữ cái và khoảng trắng
if (!preg_match("/^[a-zA-Z-' ]*$/", $name)) {
$nameErr = "Chỉ cho phép chữ cái và khoảng trắng";
}
}
// Validate email
if (empty($_POST["email"])) {
$emailErr = "Email không được để trống";
} else {
$email = clean_input($_POST["email"]);
// Kiểm tra định dạng email
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$emailErr = "Định dạng email không hợp lệ";
}
}
// Nếu không có lỗi, chuyển hướng sang trang khác
if (empty($nameErr) && empty($emailErr)) {
header("Location: success.php");
exit();
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Form Đăng Ký</title>
</head>
<body>
<h2>Form Đăng Ký</h2>
<p><span class="error">* bắt buộc</span></p>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Tên: <input type="text" name="name" value="<?php echo $name;?>">
<span class="error">* <?php echo $nameErr;?></span>
<br><br>
Email: <input type="email" name="email" value="<?php echo $email;?>">
<span class="error">* <?php echo $emailErr;?></span>
<br><br>
<input type="submit" name="submit" value="Đăng Ký">
</form>
</body>
</html>
```
**Trong mã trên:**
- Form được xử lý bởi cùng một trang (`form.php`).
- Dữ liệu được validate ngay khi form được gửi.
- Các thông báo lỗi được hiển thị bên cạnh mỗi trường nhập liệu.
- Dữ liệu được giữ lại trong các trường nhập liệu nếu có lỗi xảy ra.
### Bước 2: Tạo Trang Đích `success.php`
Đảm bảo rằng bạn đã tạo trang `success.php` để người dùng được chuyển hướng đến nếu không có lỗi.
```html
<!DOCTYPE html>
<html>
<head>
<title>Đăng Ký Thành Công</title>
</head>
<body>
<h1>Chúc mừng! Bạn đã đăng ký thành công.</h1>
</body>
</html>
```