PHP - $_FILES: Handling File Uploads in PHP

Hello, aspiring PHP developers! Today, we're going to dive into one of the most exciting aspects of web development: handling file uploads. As your friendly neighborhood computer science teacher, I'm here to guide you through the ins and outs of the $_FILES superglobal in PHP. So, grab your favorite beverage, get comfortable, and let's embark on this file-uploading adventure together!

PHP - $_FILES

What is $_FILES?

Before we jump into the code, let's understand what $_FILES is all about. In PHP, $_FILES is a superglobal array that contains information about uploaded files. When a user submits a form with file inputs, PHP automatically populates this array with details about the uploaded files.

Think of $_FILES as a magical box that captures all the important information about the files your users are trying to send to your server. It's like having a personal assistant who meticulously organizes all the file-related data for you!

Structure of $_FILES

Let's take a look at the structure of the $_FILES array:

Key Description
name The original name of the file on the client machine
type The MIME type of the file
size The size of the file in bytes
tmp_name The temporary filename of the file stored on the server
error The error code associated with this file upload

Now that we know what $_FILES contains, let's dive into some practical examples!

Example 1: Basic File Upload

Let's start with a simple example of uploading a single file.

HTML Form

<form action="upload.php" method="post" enctype="multipart/form-data">
    Select image to upload:
    <input type="file" name="fileToUpload" id="fileToUpload">
    <input type="submit" value="Upload Image" name="submit">
</form>

PHP Script (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 "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded.";
    } else {
        echo "Sorry, there was an error uploading your file.";
    }
}
?>

In this example, we're doing several things:

  1. We check if the form has been submitted.
  2. We define a target directory for our uploads.
  3. We construct the target file path using the original filename.
  4. We use move_uploaded_file() to move the uploaded file from its temporary location to our target directory.
  5. Finally, we provide feedback to the user about the success or failure of the upload.

Remember, my dear students, always validate and sanitize file uploads in a real-world scenario. We don't want any sneaky viruses creeping into our server!

Example 2: Multiple File Upload

Now, let's level up and handle multiple file uploads!

HTML Form

<form action="upload_multiple.php" method="post" enctype="multipart/form-data">
    Select images to upload:
    <input type="file" name="filesToUpload[]" id="filesToUpload" multiple>
    <input type="submit" value="Upload Images" name="submit">
</form>

PHP Script (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 "All files have been uploaded successfully.";
    } else {
        echo "Sorry, there was an error uploading one or more files.";
    }
}
?>

In this example, we're handling multiple file uploads:

  1. We use a foreach loop to iterate through each uploaded file.
  2. For each file, we construct a target path and attempt to move it.
  3. If any file fails to upload, we set a flag and break the loop.
  4. Finally, we provide feedback based on whether all files were uploaded successfully.

Pro tip: In real-world applications, you might want to provide more detailed feedback, like which specific files failed to upload and why.

Example 3: File Validation

Let's add some basic file validation to our upload process. We'll check the file size and type.

HTML Form

<form action="upload_validate.php" method="post" enctype="multipart/form-data">
    Select image to upload (Max 5MB, JPG/PNG only):
    <input type="file" name="fileToUpload" id="fileToUpload">
    <input type="submit" value="Upload Image" name="submit">
</form>

PHP Script (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));

    // Check file size
    if ($_FILES["fileToUpload"]["size"] > 5000000) {
        echo "Sorry, your file is too large. Max size is 5MB.";
        $uploadOk = 0;
    }

    // Allow certain file formats
    if($imageFileType != "jpg" && $imageFileType != "png") {
        echo "Sorry, only JPG & PNG files are allowed.";
        $uploadOk = 0;
    }

    // Check if $uploadOk is set to 0 by an error
    if ($uploadOk == 0) {
        echo "Sorry, your file was not uploaded.";
    // If everything is ok, try to upload file
    } else {
        if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
            echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded.";
        } else {
            echo "Sorry, there was an error uploading your file.";
        }
    }
}
?>

In this final example, we've added some crucial validations:

  1. We check the file size to ensure it's not larger than 5MB.
  2. We verify that the file type is either JPG or PNG.
  3. Only if both these conditions are met do we proceed with the upload.

Remember, my dear students, validation is your first line of defense against malicious uploads. Always validate thoroughly!

Conclusion

And there you have it, folks! We've journeyed through the land of $_FILES, from basic uploads to handling multiple files and even adding some validation. Remember, with great power comes great responsibility. Always sanitize and validate your uploads, and never trust user input blindly.

As we wrap up, I'm reminded of a funny story from my early days of teaching. I once had a student who tried to upload their entire music library to a simple photo-sharing project. Let's just say the server wasn't too happy about that!

Keep practicing, stay curious, and happy coding! And remember, in the world of programming, every error is just a new learning opportunity in disguise.

Credits: Image by storyset