Uploading Files
Uploading files is a process involving both the client and the server. We must ensure our forms can upload files before we can start writing PHP code.
Preparing the Client
Browsers facilitate file uploads by allowing users to select and send files to the server. Through HTML input forms and HTTP POST requests, browsers encode the file as multipart data and send it to the server, where it can process the upload.
Here's a basic example of what an upload form should look like:
<form action="upload.php" method="POST" enctype="multipart/form-data">
Select file to upload:
<input type="file" name="image" id="fileToUpload" />
<button type="submit">Upload File</button>
</form>
Preparing a form for file uploads in HTML is quite simple. Firstly, on the <form>
element, you must set the method
attribute to POST
. For file uploads, only POST
requests are supported. You cannot use GET
.
Next, you must set the encoding type. This can be done via the enctype
attribute on the <form>
element. The enctype
attribute in a <form>
element specifies how the form data should be encoded when submitted to the server.
For file uploads, the enctype attribute must be set to "multipart/form-data"
. This value is necessary for uploading files, allowing the form to send files as binary data. It splits the data into different parts, allowing files and text data to be sent together in one request.
If you exclude the enctype="multipart/form-data"
attribute from the <form>
element when trying to upload a file, the form will revert to the default encoding type, which is "application/x-www-form-urlencoded"
. This default encoding type is designed for sending simple text data and can't handle binary data like files.
Input Element
Inside the form, use an <input>
element with type="file"
to create a file input. This will allow users to select a file from their device.
<input type="file" name="image" id="fileToUpload" />
When a user selects a file and clicks the submit button, the browser will package the file and send it to the server specified in the action attribute, in this case, upload.php
.
Sometimes, you may want to limit the type of files you can upload. You can do so by setting the mime type. A MIME type (Multipurpose Internet Mail Extensions) is a standard that indicates the nature and format of a document, file, or assortment of bytes. It's used by web browsers and servers to understand how to handle different file types.
A MIME type consists of two parts: a type and a subtype, separated by a slash. For example, the MIME type for a JPEG image is image/jpeg
. You can use the accept
attribute in an <input>
element to restrict the type of files that can be selected.
Here's an example that allows only JPEG images:
<input type="file" name="image" id="fileToUpload" accept="image/jpeg" />
You can specify multiple MIME types by separating them with a comma. For example, to allow both JPEG and PNG images:
<input
type="file"
name="image"
id="fileToUpload"
accept="image/jpeg, image/png"
/>
By restricting file types, you guide users to select the correct file type, reducing the chance of errors.
Alternatively, you may want to allow all types of images. In that case, you can use the *
character for the subtype like so:
```html {5}
<input type="file" name="image" id="fileToUpload" accept="image/*" />
Server side validation still required
While restricting MIME types on the client side can be helpful, it's not foolproof. Users can bypass these restrictions, so it's crucial to validate the file types on the server side as well.
Accessing Uploaded Files
When a file is uploaded through an HTML form, you can access the uploaded file's information using the $_FILES
superglobal array. It's a specially designated variable in PHP that allows you to access file information submitted through a form with the POST method.
If you have an input field for file uploading with the name image
, you can access the uploaded file in your PHP script using $_FILES['image']
. The value of a file is an associative array. You will always find the following keys:
Key Name | Description | Code Example |
---|---|---|
name | Original name of the file | $_FILES['image']['name'] |
type | MIME type of the file | $_FILES['image']['type'] |
tmp_name | Temporary location on the server | $_FILES['image']['tmp_name'] |
error | Error code (0 means no error) | $_FILES['image']['error'] |
size | Size of the file in bytes | $_FILES['image']['size'] |
Check for Errors
Before working with a file, you should check the file was uploaded without an error. The error
key can help you verify a successful upload. The following error codes can be found:
Error Code | Constant | Description |
---|---|---|
0 | UPLOAD_ERR_OK | There is no error; the file uploaded with success. |
1 | UPLOAD_ERR_INI_SIZE | The uploaded file exceeds the upload_max_filesize in php.ini . |
2 | UPLOAD_ERR_FORM_SIZE | The uploaded file exceeds the MAX_FILE_SIZE in the HTML form. |
3 | UPLOAD_ERR_PARTIAL | The uploaded file was only partially uploaded. |
4 | UPLOAD_ERR_NO_FILE | No file was uploaded. |
6 | UPLOAD_ERR_NO_TMP_DIR | Missing a temporary folder. |
7 | UPLOAD_ERR_CANT_WRITE | Failed to write file to disk. |
8 | UPLOAD_ERR_EXTENSION | A PHP extension stopped the file upload. |
In the code example below, the page checks if the form was submitted by verifying the request method. If the method is POST, we're then checking if the error
key for the image upload has an error. We're comparing it against the UPLOAD_ERR_OK
constant, which means there is no error. If there's no error, the filename gets outputted. Otherwise, a message indicating the upload failed is displayed.
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($_FILES['image']['error'] === UPLOAD_ERR_OK) {
echo "File: {$_FILES['image']['name']} successfully uploaded!";
} else {
echo "File failed to upload";
}
}
?>
<form action="upload.php" method="POST" enctype="multipart/form-data">
Select file to upload:
<input type="file" name="image" id="fileToUpload" />
<button type="submit">Upload File</button>
</form>
Moving Uploaded Files
When a file is uploaded to a server through a PHP script, it's initially stored in a temporary location. The temporary location is a specific folder on the server where uploaded files are first stored before being processed. This location is meant to be a holding area. Files left there are automatically deleted after the script finishes executing. It's designed to give you a chance to examine and handle the file as needed without cluttering up the server with unwanted files.
By moving the file from the temporary location to a permanent directory, you ensure that it remains available after the script finishes executing. This allows you to store user uploads for future access, whether it's for download, display, or further processing. Handling the file yourself allows you to implement security measures, such as checking the file's type and size, to prevent malicious uploads.
Let's say you want to move the uploaded file from its temporary location to a specific directory on your server. PHP provides a function called move_uploaded_file()
to help you perform this task.
The move_uploaded_file()
function in PHP is used to move an uploaded file from its temporary location to a permanent location on the server. It's commonly used to handle file uploads in web applications. The function also provides a built-in security mechanism to ensure that the file is uploaded through PHP's HTTP POST upload mechanism, reducing the risk of file manipulation.
Here's the function definition:
move_uploaded_file(string $from, string $to): bool
$from
: The temporary path of the uploaded file. This is usually accessed from the$_FILES
array, specifically $_FILES['fileInputName']['tmp_name'], wherefileInputName
corresponds to thename
attribute of the file input field in the HTML form.$to
: The target path where you want to move the uploaded file. This path includes the directory and the new filename.
Here's an example usage of move_uploaded_file()
:
$tempPath = $_FILES['image']['tmp_name'];
$targetPath = 'uploads/' . $_FILES['image']['name'];
if (move_uploaded_file($tempPath, $targetPath)) {
echo 'File successfully uploaded.';
} else {
echo 'Failed to move file.';
}
In this example, $tempPath
is the temporary location of the uploaded file, and $targetPath
is the desired permanent location. If the function successfully moves the file, it returns true
; otherwise, it returns false.
Here are a few things to keep in mind:
- Make sure the target directory (
uploads/
in the example) has the correct permissions to allow writing files. - Always perform additional validations, such as checking file size and type, to enhance security and ensure that only legitimate files are processed.
- The
move_uploaded_file()
function itself checks whether the file was uploaded via an HTTP POST request, adding an extra layer of security. If the file wasn't uploaded through a POST request, the function will return false, and the move operation will fail.
Completed Code
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($_FILES['image']['error'] === UPLOAD_ERR_OK) {
$tempPath = $_FILES['image']['tmp_name'];
$targetPath = 'uploads/' . $_FILES['image']['name'];
if (move_uploaded_file($tempPath, $targetPath)) {
echo 'File successfully uploaded.';
} else {
echo 'Failed to move file.';
}
} else {
echo 'Failed to upload file.';
}
}
?>
<form method="POST" enctype="multipart/form-data">
Select file to upload:
<input type="file" name="image" id="fileToUpload" />
<button type="submit">Upload File</button>
</form>
Key Takeaways
- Use a form with
method="post"
and include theenctype="multipart/form-data"
attribute. - Include an input field with
type="file"
for selecting files. - Files are initially stored in a temporary directory on the server. Temporary files are deleted after the script finishes executing.
- Access file information using the
$_FILES
superglobal array. Contains details like name, type, size, temporary name, and error code. - Use the
move_uploaded_file()
function to move the file from the temporary location to the desired directory. - The
$_FILES['fileInputName']['error']
provides error codes for handling various upload-related errors.