Sáng Chủ Nhật đẹp trời, bạn hăng say đổ đầy nước vào hồ cá. Sau đó hớn hở đem cá tới để để đổ vào hồ thì "bàng hoàng" nhận ra hồ cá...không một giọt nước!
Bạn làm chức năng upload ảnh.Form rất đẹp.
Nút chọn file rất đẹp.
Người dùng chọn:
avatar.jpgBấm:
Upload😎
Bạn chờ đợi.
PHP trả về:
No file uploaded💀
Hoặc:
Undefined index: file💀💀
Hoặc tệ hơn:
Không báo lỗi gìNhưng file biến mất khỏi Trái Đất.
🤡
Upload file PHP không thấy file đâu là gì?
Đây là nhóm lỗi xảy ra khi:
- Người dùng đã chọn file
- Form đã submit
- Nhưng PHP không nhận được file
Hoặc:
- PHP nhận được file
- Nhưng file không được lưu
Rất phổ biến với:
- PHP thuần
- Người mới học upload
- InfinityFree
- Shared Hosting
Ví dụ trớt quớt 😭
HTML:
<form method="post">
<input type="file" name="avatar">
<button>Upload</button>
</form>PHP:
print_r($_FILES);Kết quả:
Array
(
)💀
PHP:
"Tôi không thấy file nào."
😅
Ví dụ đời thường 🍜
Bạn ra bưu điện gửi hàng.
Nhân viên hỏi:
"Kiện hàng của bạn đâu?"
Bạn trả lời:
"Tôi mang theo rồi."
Nhân viên:
"Không thấy."
Bạn nhìn xuống.
Thì ra quên mang kiện hàng từ xe vào.
🤡
Upload file lỗi thường cũng kiểu như vậy.
1. Quên enctype 😭
Đây là vua của mọi lỗi upload.
HTML sai:
<form method="post">
<input type="file" name="avatar">
</form>Nhìn hoàn toàn bình thường.
😎
Nhưng thiếu:
enctype="multipart/form-data"Đúng phải là:
<form
method="post"
enctype="multipart/form-data">
<input type="file" name="avatar">
</form>Nếu thiếu dòng này:
$_FILESthường sẽ rỗng.
🤡
2. Đọc nhầm $_POST thay vì $_FILES 😭
Sai:
$file = $_POST['avatar'];Đúng:
$file = $_FILES['avatar'];Người mới rất hay nhầm chỗ này.
3. Sai tên field
HTML:
<input type="file" name="photo">PHP:
$_FILES['avatar']🤡
PHP:
photo ≠ avatar4. Quên move_uploaded_file()
Nhiều bạn nghĩ:
$_FILESxuất hiện là xong.
Không.
File đang nằm trong thư mục tạm.
Bạn phải:
move_uploaded_file(...)Ví dụ:
move_uploaded_file(
$_FILES['avatar']['tmp_name'],
"uploads/avatar.jpg"
);Nếu không:
💀 File biến mất sau khi request kết thúc.
Ví dụ "trời ơi đất hỡi" 😵
Debug:
print_r($_FILES);Thấy file.
😎
Mở thư mục uploads:
Trống trơn🤡
Nguyên nhân:
move_uploaded_file()chưa chạy.
5. Thư mục uploads không tồn tại 😭
Code:
move_uploaded_file(
$tmp,
"uploads/avatar.jpg"
);Nhưng:
uploads/không có.
Kết quả:
💀 Upload thất bại.
6. Quyền ghi thư mục (Permission)
Một số host:
Không cho ghi filePHP nhận file.
Nhưng không lưu được.
Kết quả:
🤡
InfinityFree Case 😅
Đây là lỗi khá phổ biến.
Localhost:
😎 Upload được.
InfinityFree:
💀 Không upload được.
Nguyên nhân thường là:
- Sai đường dẫn
- Sai thư mục
- Thiếu thư mục uploads
- File quá lớn
Không phải PHP ghét bạn.
😄
7. File quá lớn 😭
Ví dụ:
video.mp4Dung lượng:
500MBHost cho:
10MBKết quả:
💀
PHP có thể báo:
UPLOAD_ERR_INI_SIZEHoặc đơn giản là thất bại.
8. Quên kiểm tra lỗi upload
PHP có sẵn:
$_FILES['avatar']['error']Ví dụ:
if($_FILES['avatar']['error'] != 0)
{
echo "Upload lỗi";
}Rất nhiều người bỏ qua bước này.
9. Sai đường dẫn 😭
Ví dụ:
uploads/avatar.jpgTrong khi thực tế:
/public_html/uploads/Kết quả:
💀
File không lưu đúng nơi.
Code upload mẫu đúng 😎
HTML
<form
method="post"
enctype="multipart/form-data">
<input type="file" name="avatar">
<button>Upload</button>
</form>PHP
<?php
if(isset($_FILES['avatar']))
{
$tmp = $_FILES['avatar']['tmp_name'];
$name = $_FILES['avatar']['name'];
move_uploaded_file(
$tmp,
"uploads/" . $name
);
echo "Upload thành công 😎";
}
?>Một sự thật thú vị 😎
Khoảng một nửa lỗi upload file của người mới là:
enctype="multipart/form-data"Chỉ thiếu đúng một dòng.
Nhưng đủ để ngốn:
2 giờ debug
3 ly cà phê
17 lần reload🤡
Debug kiểu dev thật 😎
✅ 1. In toàn bộ $_FILES
print_r($_FILES);Nếu rỗng:
👉 Kiểm tra form.
✅ 2. Kiểm tra error
var_dump(
$_FILES['avatar']['error']
);✅ 3. Kiểm tra thư mục uploads
Có tồn tại không?
✅ 4. Kiểm tra move_uploaded_file()
var_dump(
move_uploaded_file(...)
);true hay false?
✅ 5. Test trên host thật
Đừng chỉ test localhost.
😄
Checklist chuẩn không cần chỉnh 😎
☑ Có enctype="multipart/form-data"
☑ Dùng $_FILES
☑ Tên field đúng
☑ Có move_uploaded_file()
☑ Thư mục uploads tồn tại
☑ Kiểm tra quyền ghi
☑ Kiểm tra dung lượng file
☑ Kiểm tra error
☑ print_r($_FILES)
FAQ nhanh
Vì sao $_FILES rỗng?
→ Thường do thiếu:
multipart/form-dataUpload được trên localhost nhưng host fail?
→ Kiểm tra:
- thư mục uploads
- đường dẫn
- dung lượng file
move_uploaded_file() có bắt buộc không?
→ Có.
Upload ảnh cần lưu database không?
→ Thường chỉ lưu:
Tên file
Đường dẫn fileKhông lưu ảnh trực tiếp.
Bạn có thể cũng đang gặp 😭
👉 Checkbox trong PHP vì sao lúc có lúc không?
👉 PHP không nhận dữ liệu từ POST/GET
👉 Redirect sau submit form đúng cách
Tổng kết
Upload file trong PHP nghe có vẻ đơn giản:
Chọn file
↓
Upload
↓
XongNhưng thực tế có rất nhiều "cái bẫy":
- thiếu enctype
- sai $_FILES
- quên move_uploaded_file()
- thư mục không tồn tại
- file quá lớn
Và hãy nhớ:
Nếu PHP nói "Tôi không thấy file đâu"...
Thì trước khi nghi ngờ server,
hãy kiểm tra xem bạn đã mang "kiện hàng" vào đúng cửa chưa. 😆