Web Development

How I Learned File Uploads & Downloads in PHP (And Built Developer Tests Along the Way)

A practical journey of learning PHP file uploads and downloads, from fixing server issues to building secure handlers. Includes Junior, Mid, and Senior developer test questions, plus full mid-level answers.

Introduction

Learning PHP file uploads can feel confusing at first — especially when you click Upload and nothing happens.
That’s exactly how my journey started:

  • The PHP script didn't run
  • The browser showed PHP code as text
  • The form wouldn’t submit
  • And I didn’t understand why

But after troubleshooting the server, learning how PHP processes form data, and building upload/download scripts from scratch — everything finally clicked.

In this post, I’ll show you how I learned file uploads in PHP, what mistakes I made, how I fixed them, and the developer tests (Junior, Mid, Senior) I created to measure progress.
The Mid-Level test includes full answers.

Step 1 — PHP Doesn’t Run

At the beginning, I tried opening: upload.php

But instead of code running, I got:

  • Raw PHP printed as text
  • A white blank page
  • No upload behavior

Why?
Because PHP must run through a server, not by opening the file directly.
I also tried:

php -S localhost:8000/upload.php

Step 2 — Running the PHP Server Correctly

The right way was to navigate to my project folder:

cd myproject
php -S localhost:8000

Then open:

http://localhost:8000/index.html

After doing that, the form finally executed the PHP script.

Step 3 — Understanding How File Uploads Work

Here’s the first working form I created:

<form action="upload.php" method="post" enctype="multipart/form-data">
    <input type="file" name="myfile">
    <button type="submit" name="submit">Upload</button>
</form>

Key lessons:

- enctype="multipart/form-data" is mandatory

- A named submit button triggers $_POST["submit"]

- Uploaded file info is always in $_FILES

- move_uploaded_file() safely stores the file

Once these pieces came together, uploads worked flawlessly.

Step 4 — Implementing File Downloads

File downloads taught me about headers. A simple version looks like this:

header('Content-Disposition: attachment; filename="file.ext"');
readfile("uploads/file.ext");

This tells the browser:

“Download this file, don’t display it.”

Step 5 — Creating Developer Skill Tests

To measure progress (and help evaluate other developers), I created three tests:

Junior → basic PHP

Mid-Level → practical uploads & security

Senior → architecture, S3, chunked uploads, queues

Below are all the tests — with mid-level answers included.

Junior PHP Developer Test (Questions Only)

  1. What does $_POST contain?
  2. What does $_FILES contain after a file upload?
  3. What does move_uploaded_file() do?
  4. How do you start PHP code inside HTML?
  5. Create a simple file upload form.
  6. Create a simple file upload handler.

Mid-Level PHP Developer Test (Questions + Answers)

  1. What is the purpose of enctype="multipart/form-data"?

Allows binary data (like files) to be sent with the form. Required for uploads.

  1. Difference between tmp_name and name?

tmp_name: Temporary location of uploaded file on server

name: Original filename from user’s computer

  1. Name three file upload security risks and mitigations.
Risk Prevention
Malicious file types Validate MIME type
Oversized uploads Max file size checks
Directory traversal Use basename() and sanitize
  1. Why is move_uploaded_file() safer than copy()?

It only moves files uploaded through PHP’s upload process, preventing file injection.

  1. Required headers for forced download?
Content-Type: application/octet-stream
Content-Disposition: attachment
Content-Length: <size>
  1. What happens when post_max_size is exceeded?

The entire POST request is dropped, and $_FILES becomes empty.

Mid-Level Practical Tasks

Task 1: Secure Upload Handler (Images Only)

<?php

header("Content-Type: application/json");

if (!isset($_FILES['file'])) {
    echo json_encode(["status" => "error"]);
    exit;
}

$file = $_FILES['file'];

if ($file['error'] !== UPLOAD_ERR_OK) {
    echo json_encode(["status" => "error"]);
    exit;
}

if ($file['size'] > 2 * 1024 * 1024) { // 2MB
    echo json_encode(["status" => "error"]);
    exit;
}

$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);

$allowed = ['image/jpeg', 'image/png'];

if (!in_array($mime, $allowed)) {
    echo json_encode(["status" => "error"]);
    exit;
}

$ext = $mime === 'image/png' ? 'png' : 'jpg';
$newName = "user_" . time() . "." . $ext;

move_uploaded_file($file['tmp_name'], "uploads/" . $newName);

echo json_encode(["status" => "success", "file" => $newName]);

Task 2: Secure File Download Script

<?php

if (!isset($_GET['file'])) exit("Missing file");

$file = basename($_GET['file']); // Prevent traversal
$path = "uploads/" . $file;

if (!file_exists($path)) exit("Not found");

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $file . '"');
readfile($path);
exit;

Senior PHP Developer Test (Questions Only)

  1. Design a chunked file upload system for files >500MB.

Include backend endpoints and chunk assembly algorithm.

  1. Describe a virus-scanning pipeline using PHP, Redis, and ClamAV.

Show queue flow and worker design.

  1. Implement time-limited signed URLs using HMAC-SHA256.

Explain how to generate and validate URLs.

  1. Describe how to upload files to AWS S3 using pre-signed URLs.

Include redirect flow and validation.

  1. Write PHPUnit tests for a file upload service.

Test invalid type, oversized file, failed move, missing tmp file.

  1. Design a microservice for file storage.

Include authentication (JWT), rate limiting, API routes, and DB schema.

Conclusion

I started this journey confused by PHP not executing my upload script. By learning how the server works, how forms submit data, and how files are validated, I was able to build:

  • secure upload handlers

  • safe download scripts

  • multiple file upload systems

  • developer evaluation tests for every level

View all Posts

Subscribe to Newsletter

Provide your email to get email notifications when we launch new products or publish new articles.