PHP - $_FILES: Xử lý Tải Lên Tệp trong PHP

Xin chào, các bạn đang học lập trình PHP! Hôm nay, chúng ta sẽ cùng nhau khám phá một trong những khía cạnh thú vị nhất của phát triển web: xử lý việc tải lên tệp. Là người giáo viên khoa học máy tính gần gũi của bạn, tôi sẽ hướng dẫn bạn qua những điều cơ bản và chi tiết của superglobal $_FILES trong PHP. Hãy chuẩn bị đồ uống yêu thích của bạn, thư giãn và cùng tôi bắt đầu hành trình tải lên tệp này nhé!

PHP - $_FILES

$_FILES là gì?

Trước khi chúng ta nhảy vào mã, hãy hiểu rõ $_FILES là gì. Trong PHP, $_FILES là một superglobal array chứa thông tin về các tệp được tải lên. Khi một người dùng gửi form có các input tệp, PHP sẽ tự động điền đầy array này với các chi tiết về các tệp được tải lên.

Hãy tưởng tượng $_FILES như một hộp ma thuật bắt được tất cả các thông tin quan trọng về các tệp mà người dùng của bạn đang cố gắng gửi lên máy chủ của bạn. Nó giống như có một trợ lý cá nhân cẩn thận sắp xếp tất cả các dữ liệu liên quan đến tệp cho bạn!

Cấu trúc của $_FILES

Hãy cùng nhìn vào cấu trúc của array $_FILES:

Key Mô tả
name Tên gốc của tệp trên máy khách
type Loại MIME của tệp
size Kích thước của tệp tính bằng byte
tmp_name Tên tệp tạm thời của tệp lưu trữ trên máy chủ
error Mã lỗi liên quan đến việc tải lên tệp

Bây giờ chúng ta đã biết $_FILES chứa gì, hãy cùng vào một số ví dụ thực tế!

Ví dụ 1: Tải lên Tệp Cơ bản

Hãy bắt đầu với một ví dụ đơn giản về việc tải lên một tệp.

Form HTML

<form action="upload.php" method="post" enctype="multipart/form-data">
Chọn ảnh để tải lên:
<input type="file" name="fileToUpload" id="fileToUpload">
<input type="submit" value="Tải lên Ảnh" name="submit">
</form>

Script PHP (upload.php)

<?php
if(isset($_POST["submit"])) {
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);

if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
echo "Tệp ". basename( $_FILES["fileToUpload"]["name"]). " đã được tải lên.";
} else {
echo "Xin lỗi, có lỗi xảy ra khi tải lên tệp của bạn.";
}
}
?>

Trong ví dụ này, chúng ta đã thực hiện một số việc:

  1. Kiểm tra xem form đã được gửi hay chưa.
  2. Định nghĩa một thư mục đích cho các tệp tải lên.
  3. Xây dựng đường dẫn tệp đích sử dụng tên gốc của tệp.
  4. Sử dụng move_uploaded_file() để di chuyển tệp từ vị trí tạm thời lên thư mục đích.
  5. Cuối cùng, cung cấp phản hồi cho người dùng về thành công hay thất bại của việc tải lên.

Nhớ rằng, các em học sinh yêu quý, luôn validate và làm sạch các tệp tải lên trong tình huống thực tế. Chúng ta không muốn bất kỳ virus nào lẻn vào máy chủ của mình!

Ví dụ 2: Tải lên Nhiều Tệp

Bây giờ, hãy nâng cấp và xử lý việc tải lên nhiều tệp!

Form HTML

<form action="upload_multiple.php" method="post" enctype="multipart/form-data">
Chọn ảnh để tải lên:
<input type="file" name="filesToUpload[]" id="filesToUpload" multiple>
<input type="submit" value="Tải lên Ảnh" name="submit">
</form>

Script PHP (upload_multiple.php)

<?php
if(isset($_POST["submit"])) {
$target_dir = "uploads/";
$upload_success = true;

foreach($_FILES["filesToUpload"]["tmp_name"] as $key => $tmp_name) {
$target_file = $target_dir . basename($_FILES["filesToUpload"]["name"][$key]);

if (!move_uploaded_file($tmp_name, $target_file)) {
$upload_success = false;
break;
}
}

if ($upload_success) {
echo "Tất cả các tệp đã được tải lên thành công.";
} else {
echo "Xin lỗi, có lỗi xảy ra khi tải lên một hoặc nhiều tệp.";
}
}
?>

Trong ví dụ này, chúng ta đang xử lý việc tải lên nhiều tệp:

  1. Sử dụng một vòng lặp foreach để duyệt qua mỗi tệp được tải lên.
  2. Đối với mỗi tệp, xây dựng một đường dẫn tệp đích và thử di chuyển nó.
  3. Nếu bất kỳ tệp nào không tải lên thành công, đặt cờ và thoát khỏi vòng lặp.
  4. Cuối cùng, cung cấp phản hồi dựa trên việc liệu tất cả các tệp có được tải lên thành công hay không.

Lời khuyên chuyên nghiệp: Trong ứng dụng thực tế, bạn có thể muốn cung cấp phản hồi chi tiết hơn, ví dụ như哪些 tệp cụ thể không tải lên và lý do tại sao.

Ví dụ 3: Validate Tệp

Hãy thêm một chút validate cơ bản vào quy trình tải lên tệp. Chúng ta sẽ kiểm tra kích thước và loại tệp.

Form HTML

<form action="upload_validate.php" method="post" enctype="multipart/form-data">
Chọn ảnh để tải lên (Tối đa 5MB, chỉ JPG/PNG):
<input type="file" name="fileToUpload" id="fileToUpload">
<input type="submit" value="Tải lên Ảnh" name="submit">
</form>

Script PHP (upload_validate.php)

<?php
if(isset($_POST["submit"])) {
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));

// Kiểm tra kích thước tệp
if ($_FILES["fileToUpload"]["size"] > 5000000) {
echo "Xin lỗi, tệp của bạn quá lớn. Kích thước tối đa là 5MB.";
$uploadOk = 0;
}

// Cho phép các định dạng tệp cụ thể
if($imageFileType != "jpg" && $imageFileType != "png") {
echo "Xin lỗi, chỉ cho phép các tệp JPG & PNG.";
$uploadOk = 0;
}

// Kiểm tra nếu $uploadOk được đặt thành 0 do lỗi
if ($uploadOk == 0) {
echo "Xin lỗi, tệp của bạn không được tải lên.";
// Nếu mọi thứ đều ổn, thử tải lên tệp
} else {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
echo "Tệp ". basename( $_FILES["fileToUpload"]["name"]). " đã được tải lên.";
} else {
echo "Xin lỗi, có lỗi xảy ra khi tải lên tệp của bạn.";
}
}
}
?>

Trong ví dụ cuối cùng này, chúng ta đã thêm một số validate quan trọng:

  1. Kiểm tra kích thước tệp để đảm bảo nó không vượt quá 5MB.
  2. Xác minh rằng loại tệp là JPG hoặc PNG.
  3. Chỉ nếu cả hai điều kiện này được满足, chúng ta mới tiếp tục với việc tải lên.

Nhớ rằng, các em học sinh yêu quý, validate là hàng phòng thủ đầu tiên của bạn chống lại các tệp độc hại. Luôn validate kỹ lưỡng!

Kết luận

Và thế là chúng ta đã cùng nhau hành trình qua thế giới $_FILES, từ việc tải lên cơ bản đến xử lý nhiều tệp và thậm chí thêm validate. Nhớ rằng, với quyền lực lớn đi kèm với trách nhiệm lớn. Luôn làm sạch và validate các tệp tải lên, và đừng bao giờ tin tưởng vào dữ liệu người dùng một cách mù quáng.

Khi chúng ta kết thúc, tôi nhớ lại một câu chuyện hài từ những ngày đầu dạy học. Tôi từng có một học sinh cố gắng tải lên toàn bộ thư viện nhạc của mình lên một dự án chia sẻ ảnh đơn giản. Nói chung, máy chủ không quá vui vẻ với điều đó!

Tiếp tục thực hành, 保持好奇心, và chúc các bạn lập trình vui vẻ! Và hãy nhớ, trong thế giới lập trình, mỗi lỗi đều là một cơ hội học tập mới ẩn sau.

Credits: Image by storyset