Không có gì bực mình hơn việc hì hục viết vài trang tài liệu, chưa kịp lưu lại, đứng lên làm ly cà phê, một ai đó "động tay chân" vào máy tính và làm công sức mấy tiếng đồng hồ "đổ sông đổ bể".
Nếu bạn mới bước vào con đường "ngâm cứu" PHP, có thể bạn đã từng gặp tình huống "chán chường" sau với form:
Sau khi "mất cả buổi sáng" để điền đầy đủ:
- Họ tên
- Số điện thoại
- Địa chỉ
- Nội dung góp ý
Hồ hởi nhấn:
Submit
PHP làm nhiệm vụ của mình là kiểm tra mọi thứ.
Phát hiện:
Email không hợp lệ
Trang web "nghênh ngang" reload.
Và...
Toàn bộ dữ liệu bạn đã "hì hục" nhập vào với mọi "tâm huyết" đã biến mất.
Người dùng:
Tôi đã điền thông tin rồi mà? Biến đâu hết rồi?
Website vô tư, ngơ ngác:
Có thấy gì đâu...?
Form reload là gì?
Ví dụ:
<form method="post">
Khi nhấn Submit:
Browser gửi request tới server.
PHP xử lý.
Sau đó trang được tải lại.
Cho tới lúc này, đây là hành vi hoàn toàn bình thường.
Vấn đề nằm ở đâu?
Lính mới thường nghĩ:
PHP đã nhận dữ liệu rồi mà?
Đúng.
PHP nhận được.
Nhưng sau khi xử lý xong.
Mọi thứ biến mất.
Kiểu như đi siêu thị, trả tiền cho thu ngân xong, ung dung đợi tiền thừa thối lại...Nhìn qua thu ngân thì thấy "chị ấy" mỉm cười ngước nhìn khách với cặp mắt "trong sáng"...đợi khách trả tiền...
Ví dụ:
$name = $_POST['name'];
Request kết thúc.
Biến:
$name
cũng kết thúc theo.
Triệu chứng thường gặp
Người dùng nhập:
- Tên: Nguyễn Văn A
- Email: abc@gmail.com
- Điện thoại: 090...
Submit.
PHP báo:
Email đã tồn tại, nhưng cần "chỉnh lại một chút"
Nhưng form:
- Tên:
- Email:
- Điện thoại:
trống trơn.
Người dùng lúc này bắt đầu nhức đầu và...tức như "bò đá"...Cái gọi là chỉnh lại "một chút" biến thành "hành xác" lại mọi thứ từ đầu! Làm như...rảnh lắm vậy.
Nguyên nhân số 1: Không đổ dữ liệu trở lại form
Ví dụ:
<input type="text" name="name">
Form sẽ luôn trống.
Cần làm:
<input
type="text"
name="name"
value="<?php echo $_POST['name'] ?? ''; ?>">Khi reload.
Dữ liệu sẽ quay lại.
Toán học của sự bực bội
Form có:
2 trường cần điền thông tin
Người dùng còn kiên nhẫn.
Form có:
20 trường
Và nếu dữ liệu mất.
Người dùng khả năng cao:
Alt + F4 (Bye bye!!)
Nguyên nhân số 2: Validation thất bại
Ví dụ:
if(empty($_POST['email']))
{
echo "Email bắt buộc";
}Thông báo hiện.
Nhưng dữ liệu không được giữ lại.
Người dùng phải nhập lại từ đầu.
Cách đơn giản nhất
Ví dụ:
$name = $_POST['name'] ?? '';
Sau đó:
<input
type="text"
name="name"
value="<?php echo htmlspecialchars($name); ?>">Mỗi lần reload.
Giá trị vẫn còn.
Nguyên nhân số 3: Redirect sau Submit
Ví dụ:
header("Location:index.php");
Khi redirect.
Toàn bộ POST biến mất.
Đây là hành vi bình thường.
Không phải lỗi PHP.
Vì sao?
POST chỉ tồn tại trong request hiện tại.
Sau redirect:
Browser tạo request mới.
POST cũ không còn.
Cách xử lý
Lưu dữ liệu vào:
$_SESSION
Ví dụ:
$_SESSION['name'] = $_POST['name'];
Sau redirect:
echo $_SESSION['name'];
vẫn còn.
Nguyên nhân số 4: Refresh trang
Một số người:
Submit
↓
F5
POST có thể bị gửi lại.
Hoặc dữ liệu mất.
Tùy cách code.
Giải pháp chuyên nghiệp
Mô hình:
POST
↓
Xử lý
↓
Redirect
↓
GET
gọi là:
PRG
(Post Redirect Get)
Đây là cách rất nhiều website lớn sử dụng.
Lỗi hay xảy ra
Bạn submit form.
PHP báo:
Đăng ký thành công
Nhưng refresh.
Thông báo biến mất.
Dữ liệu biến mất.
Bạn tưởng:
PHP bị lỗi
Thực ra:
Biến POST đã hết vòng đời.
Ví dụ thực tế
Hãy tưởng tượng:
Bạn gửi một lá thư.
PHP nhận được thư.
Đọc xong.
Vứt thư vào thùng rác.
Nếu muốn giữ nội dung.
Bạn phải:
sao chép vào sổ tay
hoặc lưu vào database
- Session giống cuốn sổ tay.
- Database giống tủ hồ sơ.
- POST giống tờ giấy tạm.
Sai lầm của lính mới
$name = $_POST['name'];
}
if($_SERVER['REQUEST_METHOD']=='POST')
{
$name = $_POST['name'];
}Xong.
Tưởng rằng:
$name
sẽ tồn tại mãi mãi.
Không.
Nó chỉ sống trong request hiện tại.
Debug kiểu dev "xịn sò"
Thêm:
print_r($_POST);
Nếu thấy:
Array
(
)sau reload.
Bạn đã tìm ra nguyên nhân.
Kinh nghiệm thực tế
Khi làm những thứ như:
- Form đăng ký
- Form liên hệ
- Form đặt hàng
- Form góp ý
Bạn nên luôn tự hỏi:
Nếu submit thất bại thì dữ liệu có bị mất không? Có phải điền lại mọi thứ từ đầu không?
Nếu câu trả lời là:
Có, thì nên sửa ngay.
Kết luận
Form reload làm mất dữ liệu không phải vì PHP muốn "hành hạ" bạn.
Mà vì:
POST chỉ tồn tại trong request hiện tại.
Khi trang tải lại hoặc redirect:
POST biến mất.
Muốn giữ dữ liệu, bạn cần:
- đổ dữ liệu trở lại form
- dùng Session
- hoặc lưu vào Database
Và hãy nhớ:
Người dùng rất "oải" nếu bắt họ nhập lại 20 ô thông tin chỉ vì quên một dấu @ trong email.
Tin vui là đây là một trong những lỗi dễ sửa nhất khi làm web PHP.
Có thể bạn cũng đang gặp: