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!
Giả sử bạn đang "vọc" PHP. 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.jpg
Bấ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ụ thực tế
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.
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:
$_FILES
thường sẽ rỗng.
Đọ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.
Sai tên field
HTML:
<input type="file" name="photo">
PHP:
$_FILES['avatar']
PHP:
photo ≠ avatar
Quên move_uploaded_file()
Nhiều bạn nghĩ:
$_FILES
xuấ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.
Thư mục uploads không tồn tại
Code:
move_uploaded_file(
$tmp,
"uploads/avatar.jpg"
);
Nhưng thu mục:
uploads/
hoàn toàn không có.
Kết quả:
Upload thất bại. Thành công mới là lạ!
Quyền ghi thư mục (Permission)
Một số host:
Không cho ghi file
PHP nhận file.
Nhưng không lưu được.
Kết quả thì không nói ra ai cũng hiểu!
Tập tành làm web
Đâ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.
File quá lớn
Ví dụ:
video.mp4
Dung lượng:
500MB
Host cho:
10MB
Kết quả:
PHP có thể báo:
UPLOAD_ERR_INI_SIZE
Hoặc đơn giản là thất bại.
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.
Sai đường dẫn
Ví dụ:
uploads/avatar.jpg
Trong 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 "xịn sò"
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. Hoàn toàn có thể dùng những dịch vụ free hosting để làm việc đó.
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-data
Upload đượ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 file
Khô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