Handling file uploads requires coordination between the HTML form and the PHP server-side script. It is a critical function for user avatars, document submissions, and photo galleries.
1. The HTML Form Requirement
To upload files, your HTML form must have two specific attributes set:
method="post": Uploads must use the POST method.enctype="multipart/form-data": This tells the browser to encode the data, including the file’s binary content, into separate parts.
Example Form:
<form action="upload_script.php" method="post" enctype="multipart/form-data">
Select file to upload (Max 5MB):
<input type="file" name="user_document" id="fileToUpload">
<input type="submit" value="Upload File" name="submit">
</form>
2. The $_FILES Superglobal
When a file is submitted, PHP automatically stores it in a temporary location on the server and populates the $_FILES superglobal array with details.
The structure of the $_FILES array is keyed by the input field’s name attribute (e.g., "user_document").
| Key | Description | Example Value |
name | The original filename (e.g., "report.pdf"). | |
type | The file’s MIME type (e.g., "application/pdf"). | |
size | The size of the file in bytes (e.g., 124500). | |
tmp_name | The temporary path on the server where the file is stored (e.g., /tmp/php4c3f56). This is where the file currently resides. | |
error | The error code (0 means success, others indicate failure). |
Example of Accessing Data:
<?php
// Assuming the input name is "user_document"
$original_name = $_FILES['user_document']['name'];
$temp_path = $_FILES['user_document']['tmp_name'];
?>
3. The Upload Workflow (4 Steps)
The actual processing of the upload must follow a strict, security-focused workflow:
Step 1: Check for Errors and Size Limits
Always check the built-in error codes and the file size before proceeding.
PHP
Step 2: Check File Type and Extension
Never trust the MIME type (type). Always check the file extension to prevent users from uploading executable scripts (like .php or .exe).
<?php
$allowed_extensions = array("jpg", "png", "pdf");
// Get the extension from the original filename
$file_ext = strtolower(pathinfo($original_name, PATHINFO_EXTENSION));
if (!in_array($file_ext, $allowed_extensions)) {
die("File type not allowed. Only JPG, PNG, and PDF.");
}
?>
Step 3: Define a Unique Target Path
To prevent security issues and file name conflicts, you should never use the original filename. Generate a unique name for the saved file.
<?php
// Define the permanent directory to store uploads (must have write permissions)
$target_dir = "uploads/";
// Create a unique filename (e.g., based on time or a random hash)
$new_file_name = uniqid("upload_", true) . "." . $file_ext;
$target_path = $target_dir . $new_file_name;
?>
Step 4: Move the File
This is the only function that moves the file from the server’s temporary storage to your defined permanent directory.
| Function | Purpose |
move_uploaded_file(temp_path, new_path) | Crucial: Checks if the file was genuinely uploaded via HTTP POST and then moves it safely. |
<?php
if (move_uploaded_file($temp_path, $target_path)) {
echo "The file " . htmlspecialchars($original_name) . " has been uploaded and saved as " . $new_file_name;
} else {
echo "There was an error moving the file.";
}
?>
⏭️ Next Steps
You have now mastered all the core mechanics of procedural PHP, including the complex security-focused task of file uploads. The next step is a major paradigm shift to the modern way of writing professional, large-scale applications.
