move_uploaded_file()
The move_uploaded_file() function is a built-in PHP function that moves an uploaded file to a new location. This function takes two parameters: the temporary
What is the move_uploaded_file() Function?
The move_uploaded_file() function is a built-in PHP function that moves a file uploaded through an HTML form to a permanent location on the server. When a browser uploads a file, PHP first stores it in a temporary directory with a random name. That temporary file is deleted automatically when the script finishes, so you must move it somewhere permanent if you want to keep it — that is exactly what move_uploaded_file() is for.
What makes this function special is its built-in safety check. It only moves a file if PHP confirms the file was genuinely uploaded via an HTTP POST request. This prevents an attacker from tricking your script into moving a sensitive server file (like /etc/passwd) by supplying its path. For that reason you should always use move_uploaded_file() instead of copy() or rename() for handling uploads.
This page covers the syntax, parameters, return value, a complete working example, the upload error codes you should check, and the security gotchas to watch for.
Syntax
move_uploaded_file(string $from, string $to): bool| Parameter | Description |
|---|---|
$from | The temporary filename of the uploaded file. Use $_FILES['field']['tmp_name']. |
$to | The full destination path, including the new filename, where the file should be saved. |
Return value
move_uploaded_file() returns true if the file was moved successfully. It returns false if $from is not a valid uploaded file (for example, if the path was forged) or if the move itself fails — typically a missing destination directory or insufficient write permissions. In the forged-file case PHP also emits a warning, and no move is performed.
How to Use the move_uploaded_file() Function?
Using the move_uploaded_file() function is straightforward. Here are the steps to follow:
- Verify the file upload succeeded by checking
$_FILES['file']['error']. - Specify the destination path for the file.
- Call the
move_uploaded_file()function, passing in the temporary filename and the destination path.
Here's an example code snippet that demonstrates how to use the move_uploaded_file() function:
How to Use the move_uploaded_file() Function?
<?php
if ($_FILES['file']['error'] === UPLOAD_ERR_OK) {
$uploaded_file = $_FILES['file']['tmp_name'];
$destination_path = '/path/to/new/location/' . basename($_FILES['file']['name']);
if (move_uploaded_file($uploaded_file, $destination_path)) {
echo "File uploaded successfully!";
} else {
echo "Error uploading file.";
}
} else {
echo "File upload failed.";
}In this example, we first verify that the upload succeeded using $_FILES['file']['error']. We then specify the destination path for the file and use basename() to safely extract the filename and prevent path traversal vulnerabilities. Finally, we use the move_uploaded_file() function to move the uploaded file to the new location. If the file is moved successfully, we print out a success message. If there is an error moving the file, we print out an error message.
The matching HTML form must use method="post" and enctype="multipart/form-data", otherwise $_FILES will be empty:
<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="Upload">
</form>The name attribute of the file input (file here) is the key you read from $_FILES.
Upload Error Codes
The $_FILES['file']['error'] value tells you whether and why an upload failed. Always check it before moving the file. The most common codes are:
| Constant | Meaning |
|---|---|
UPLOAD_ERR_OK (0) | Upload succeeded — safe to move the file. |
UPLOAD_ERR_INI_SIZE (1) | File exceeds upload_max_filesize in php.ini. |
UPLOAD_ERR_FORM_SIZE (2) | File exceeds the form's MAX_FILE_SIZE field. |
UPLOAD_ERR_PARTIAL (3) | The file was only partially uploaded. |
UPLOAD_ERR_NO_FILE (4) | No file was uploaded. |
Two server settings frequently cause silent failures: upload_max_filesize and post_max_size. If the uploaded file is larger than either limit, $_FILES may arrive empty or with an error code, no matter how correct your PHP code is.
Security Notes
- Never trust the original filename. Use
basename()on$_FILES['file']['name'], or better, generate your own safe name, to avoid path traversal like../../config.php. - Validate the file type by its actual contents (for example with
finfo/mime_content_type), not just its extension — the client can lie about both the extension and thetypefield. - Store uploads outside the web root when possible, so users can't execute uploaded scripts directly.
- For an explicit double-check that a path is a real uploaded file, see
is_uploaded_file()— thoughmove_uploaded_file()already performs this verification internally.
Conclusion
The move_uploaded_file() function is the correct, secure way to move an HTTP-POST-uploaded file from PHP's temporary directory to a permanent location. It returns true on success and false on failure, and it refuses to move anything that was not genuinely uploaded. Always check the upload error code first, sanitize the destination filename, and validate the file before trusting it.
For the broader workflow around handling uploads, see PHP File Upload and the rest of PHP File Handling.