Thứ Hai, 15 tháng 6, 2026

Upload File PHP – Lỗi "Không thấy file đâu" (Khi người dùng chọn file rất tự tin... nhưng server khẳng định chưa từng gặp nó)

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.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ụ đờ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:

$_FILES

thườ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 ≠ avatar

4. 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.


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 file

PHP 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.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.


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.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 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-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 😭

👉 Form reload mất dữ liệu

👉 Checkbox trong PHP vì sao lúc có lúc không?

👉 PHP không nhận dữ liệu từ POST/GET

👉 Undefined Variable

👉 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
↓
Xong

Như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. 😆