PHP File Upload

PHP receives files sent from an HTML form through the $_FILES superglobal, letting you validate and move an uploaded file to permanent storage on the server.

Setting up the upload form

File uploads start in the browser with an HTML form. Two attributes are essential: the form's method must be POST, and its enctype must be set to 'multipart/form-data'. Without the correct enctype the file's contents will not be transmitted. The input element uses type='file' so the browser shows a file picker.

The HTML upload form

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

Reading the file in PHP

When the form is submitted, PHP places details about the file in the $_FILES superglobal, keyed by the input's name. Each entry is an array holding the original name, the MIME type, a temporary path on the server, an error code, and the size in bytes. The uploaded file lives in a temporary location until you move it somewhere permanent with move_uploaded_file().

$_FILES keyContains
nameOriginal file name from the user's device
typeMIME type reported by the browser
tmp_nameTemporary path where PHP stored the upload
errorError code, 0 means success (UPLOAD_ERR_OK)
sizeFile size in bytes

Validating and saving the upload

<?php
if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $file = $_FILES["photo"];

    if ($file["error"] === UPLOAD_ERR_OK) {
        $allowed = ["image/jpeg", "image/png"];
        if (in_array($file["type"], $allowed) && $file["size"] < 2000000) {
            $target = "uploads/" . basename($file["name"]);
            if (move_uploaded_file($file["tmp_name"], $target)) {
                echo "Upload complete.";
            }
        } else {
            echo "Only JPG or PNG under 2 MB are allowed.";
        }
    }
}
?>
Note: Never trust the file name or MIME type sent by the browser. Use basename() to strip directory parts, generate your own file names when possible, and verify the file type on the server before storing it.

Server settings that affect uploads

PHP limits uploads through settings in php.ini. If a large file silently fails, these values are usually the reason. Knowing them helps you diagnose why an upload did not arrive as expected.

  • file_uploads must be On for uploads to work at all.
  • upload_max_filesize caps the size of a single uploaded file.
  • post_max_size limits the total size of the whole POST request and must be larger than upload_max_filesize.
  • upload_tmp_dir sets where the temporary file is stored during the upload.
  • Always confirm the target folder exists and the web server has permission to write to it.

Reading key upload details safely

<?php
$file = $_FILES["photo"] ?? null;

if ($file && $file["error"] === UPLOAD_ERR_OK) {
    $sizeKb = round($file["size"] / 1024, 1);
    echo "Received: " . htmlspecialchars($file["name"]) . "\n";
    echo "Size: {$sizeKb} KB\n";
} else {
    echo "No valid file was uploaded.";
}
?>