Skip to main content
PHP Backend Development Tutorial
CHAPTER 11 Beginner

PHP File Uploads and File Handling

Updated: May 14, 2026
25 min read

# CHAPTER 11

PHP File Uploads and File Handling

1. Introduction

Handling text strings in a form is straightforward, but what happens when a user wants to upload a profile picture or a PDF document? Handling physical files requires an entirely different workflow. The backend must catch the file, inspect it for malicious code, and move it to a permanent folder on the server. In this chapter, we will learn how to handle file uploads securely.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Configure an HTML form to allow file uploads.
  • Access uploaded files using the $_FILES superglobal.
  • Validate file types and file sizes.
  • Move a temporary file to a permanent storage directory on the server.

3. Beginner-Friendly Explanation

When you attach a photo to an email, your browser doesn't send the literal image pixel by pixel. It converts the image into a massive block of raw data and attaches it to the HTTP request. However, standard HTML forms don't know how to carry this heavy luggage. You have to explicitly tell the HTML form to become a "cargo transport" (by adding enctype="multipart/form-data"). When the cargo arrives at the Server, PHP places the file in a temporary holding area. The developer's script must inspect the cargo (Is it actually an image? Is it too heavy?) and then physically move the cargo from the holding area to the final warehouse folder.

4. The HTML Upload Form

To upload a file, the form MUST use the POST method, and MUST include the enctype attribute. Without it, PHP will never receive the file.
html
123456
<!-- The enctype attribute is mandatory for file uploads -->
<form action="upload.php" method="POST" enctype="multipart/form-data">
    <label>Select Profile Picture:</label>
    <input type="file" name="profile_pic">
    <button type="submit">Upload</button>
</form>

5. The $FILES Superglobal

Just as text data goes into $POST, uploaded files go into the $_FILES array. This array contains metadata about the file.
php
123456789
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // Look at the metadata of the uploaded file
    $file_name = $_FILES[&#039;profile_pic']['name'];       // E.g., 'me.jpg'
    $file_size = $_FILES[&#039;profile_pic']['size'];       // Size in bytes
    $tmp_location = $_FILES[&#039;profile_pic']['tmp_name']; // Where PHP temporarily hid it
    $file_error = $_FILES[&#039;profile_pic']['error'];     // Any upload errors
}
?>

6. The Upload Workflow (Validation & Movement)

Here is a complete, secure file upload script.
php
1234567891011121314151617181920212223242526272829303132333435363738394041424344
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    
    // 1. Define the final destination folder
    $target_dir = "uploads/";
    
    // 2. Get file info
    $file_name = basename($_FILES["profile_pic"]["name"]);
    $target_file = $target_dir . $file_name;
    $file_type = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
    
    $upload_ok = true;

    // 3. Validation: Check if it is a real image (not a fake extension)
    $check = getimagesize($_FILES["profile_pic"]["tmp_name"]);
    if($check === false) {
        echo "File is not a valid image.";
        $upload_ok = false;
    }

    // 4. Validation: Check file size (e.g., max 2MB)
    if ($_FILES["profile_pic"]["size"] > 2000000) {
        echo "Sorry, your file is too large.";
        $upload_ok = false;
    }

    // 5. Validation: Allow only certain file formats
    if($file_type != "jpg" && $file_type != "png" && $file_type != "jpeg") {
        echo "Sorry, only JPG, JPEG, & PNG files are allowed.";
        $upload_ok = false;
    }

    // 6. Final Execution
    if ($upload_ok) {
        // move_uploaded_file moves it from the temporary holding area to our uploads folder
        if (move_uploaded_file($_FILES["profile_pic"]["tmp_name"], $target_file)) {
            echo "The file ". $file_name . " has been uploaded.";
            // Now, you would save the string "uploads/me.jpg" into the MySQL database!
        } else {
            echo "Sorry, there was an error moving your file.";
        }
    }
}
?>

7. Saving Files to the Database

CRITICAL RULE: You almost *never* save the physical file itself inside the MySQL database. Databases are meant for text, not massive images. Instead, you save the file to a folder (like /uploads/), and you save the *text path* of that file to the database. UPDATE users SET profileimagepath = 'uploads/me.jpg' WHERE id = 5;

8. Best Practices

  • Rename Uploaded Files: Never trust the user's file name. If a user uploads index.php and you save it to your server, they could navigate to that file in their browser and hack your server. Always generate a random, unique name (like a timestamp or UUID) for the file before saving it.

9. Common Mistakes

  • Forgetting Folder Permissions: On a live Linux server, PHP must be granted "Write Permissions" (chmod 755 or 777 in rare cases) to the /uploads folder. If PHP does not have permission, moveuploadedfile() will fail silently.

10. Exercises

  1. 1. Explain the difference between $POST and $FILES when processing an HTML form submission.

11. Coding Challenges

  • Challenge: Modify the file upload script to rename the incoming file. Instead of keeping the original $filename, rename the file to userid5profilepic.jpg before moving it to the target directory.

12. MCQs with Answers

Question 1

Which HTML attribute is absolutely mandatory on a <form> tag if you want to upload a file to a PHP backend?

Question 2

When PHP receives an uploaded file, what must the developer do to ensure the file is permanently saved on the server?

13. Interview Questions

  • Q: Describe the security risks of allowing users to upload files to a server. What specific validations would you implement to ensure a user doesn't upload a malicious PHP script disguised as an image?
  • Q: Why is it standard practice to save file paths (text) in a database rather than storing the binary file data directly in the database table?

14. FAQs

Q: Can I upload a 1GB video file using standard PHP? A: By default, no. The php.ini configuration file on the server has strict limits (usually 2MB) for uploadmaxfilesize and postmaxsize. To accept large videos, you must edit the server's php.ini file to increase these limits.

15. Summary

In Chapter 11, we learned how to transport digital cargo. By modifying our HTML forms to handle multipart data, we can receive heavy files in the $FILES array. Because file uploads represent a massive security risk, we learned to rigorously validate the file type and size. Finally, by using moveuploaded_file(), we permanently stored the asset on our server, saving only its text path in our database.

16. Next Chapter Recommendation

Our application is great for web browsers, but what if we want to connect a mobile app to our database? We can't send HTML. We must send pure data. Proceed to Chapter 12: Building REST APIs with PHP.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·