In this article, I’ll explain the basics of file upload in PHP. Firstly, we’ll go through the PHP configuration options that need to be in place for successful file uploads. Following that, we’ll develop a real-world example of how to upload a file.
Configure PHP Settings
There are a couple of PHP configuration settings that you'll want to check beforehand for successful file uploads. In this section, we’ll go through each and every option which is important in regards to PHP file upload. These options can be configured in the php.ini file.
If you're not sure where to find your php.ini file, you can use the php_ini_loaded_file()
to locate it. Just create a PHP file on your server with the following line, and open it from the browser.
<?php echo php_ini_loaded_file(); ?>
Here is an excerpt from a setup file with some useful defaults.
; Whether to allow HTTP file uploads. file_uploads = On ; Temporary directory for HTTP uploaded files. ; Will use system default if not set. ;upload_tmp_dir = ; Maximum allowed size for uploaded files. upload_max_filesize = 16M ; Maximum number of files that can be uploaded via a single request max_file_uploads = 20 ; Maximum size of POST data that PHP will accept. post_max_size = 20M max_input_time = 60 memory_limit = 128M max_execution_time = 30
The Key Settings
file_uploads
The value of the file_uploads
directive should be set to On
to allow file uploads. The default value of this directive is On
.
upload_max_filesize
The upload_max_filesize
directive allows you to configure the maximum size of the uploaded file. By default, it's set to 2M
(two megabytes), and you can override this setting using the .htaccess file as well. Two megabytes isn't very much by today's standards, so you might have to increase this. If you get an error that file exceeds upload_max_filesize
when you try to upload a file, you need to increase this value. If you do, be sure to also increase post_max_size
(see below).
upload_tmp_dir
Sets a temporary directory which will be used to store uploaded files. In most cases, you don't need to worry about this setting. If you don't set it, the system default temp directory will be used.
post_max_size
The post_max_size
directive allows you to configure the maximum size of POST data. Since files are uploaded with POST requests, this value must be greater than what you've set for the upload_max_filesize
directive. For example, if your upload_max_filesize
is 16M
(16 megabytes), you might want to set post_max_size
to 20M
.
max_file_uploads
It allows you to set the maximum number of files that can be uploaded at a time. The default is 20
, a sensible amount.
max_input_time
It's the maximum number of seconds a script is allowed to parse the input data. You should set it to a reasonable value if you're dealing with large file uploads. 60
(60 seconds) is a good value for most apps.
memory_limit
The memory_limit
directive indicates the maximum amount of memory a script can consume. If you're facing issues during upload of large files, you need to make sure that the value of this directive is greater than what you've set for the post_max_size
directive. The default value is 128M
(128 megabytes), so unless you have a very large post_max_size
and upload_max_filesize
, you don't need to worry about this.
max_execution_time
It's the maximum number of seconds a script is allowed to run. If you're facing issues during upload of large files, you can consider increasing this value. 30
(30 seconds) should work well for most apps.
Now let's build a real-world example to demonstrate file upload in PHP.
Create the HTML Form
Once you’ve configured the PHP settings, you're ready to try out the PHP file upload capabilities.
Our GitHub repo has some sample code which I'm going to discuss throughout this article. So, if you want to follow along, go ahead and download it from GitHub.
We’re going to create two PHP files: index.php and upload.php. The index.php file holds code which is responsible for displaying the file upload form. On the other hand, the upload.php file is responsible for uploading a file to the server.
Also, a file will be uploaded in the uploaded_files directory, so you need to make sure that this folder exists and is writable by the web-server
user.
In this section, we’ll go through the key parts of the index.php file.
Let’s take a look at the index.php file on GitHub:
<?php session_start(); ?> <!DOCTYPE html> <html> <head> <title>PHP File Upload</title> </head> <body> <?php if (isset($_SESSION['message']) && $_SESSION['message']) { echo '<p class="notification">'.$_SESSION['message']).'</p>'; unset($_SESSION['message']); } ?> <form method="POST" action="upload.php" enctype="multipart/form-data"> <div class="upload-wrapper"> <span class="file-name">Choose a file...</span> <label for="file-upload">Browse<input type="file" id="file-upload" name="uploadedFile"></label> </div> <input type="submit" name="uploadBtn" value="Upload" /> </form> </body> </html>
You can use the following CSS to give the form a more appealing look.
div.upload-wrapper { color: white; font-weight: bold; display: flex; } input[type="file"] { position: absolute; left: -9999px; } input[type="submit"] { border: 3px solid #555; color: white; background: #666; margin: 10px 0; border-radius: 5px; font-weight: bold; padding: 5px 20px; cursor: pointer; } input[type="submit"]:hover { background: #555; } label[for="file-upload"] { padding: 0.7rem; display: inline-block; background: #fa5200; cursor: pointer; border: 3px solid #ca3103; border-radius: 0 5px 5px 0; border-left: 0; } label[for="file-upload"]:hover { background: #ca3103; } span.file-name { padding: 0.7rem 3rem 0.7rem 0.7rem; white-space: nowrap; overflow: hidden; background: #ffb543; color: black; border: 3px solid #f0980f; border-radius: 5px 0 0 5px; border-right: 0; }
The CSS basically hides the original file input
and styles its accompanying span
and label
elements.
Although it may look like a typical PHP form, there’s an important difference in the value of the enctype
attribute of the <form>
tag. It needs to be set to multipart/form-data
since the form contains the file field.
The enctype
attribute specifies the type of encoding which should be used when the form is submitted, and it takes one of the following three values:
application/x-www-form-urlencoded
: This is the default value when you don’t set the value of theenctype
attribute explicitly. In this case, characters are encoded before it’s sent to the server. If you don’t have the file field in your form, you should use this value for theenctype
attribute.multipart/form-data
: When you use themultipart/form-data
value for theenctype
attribute, it allows you to upload files using the POST method. Also, it makes sure that the characters are not encoded when the form is submitted.text/plain
: This is generally not used. With this setting, the data is sent unencoded.
Next, we output the file field, which allows you to select a file from your computer.
<input type="file" name="uploadedFile" />
Apart from that, we’ve displayed a message at the top of the form. This message shows the status of the file upload, and it’ll be set in a session variable by the upload.php script. We’ll look more at this in the next section.
<?php if (isset($_SESSION['message']) && $_SESSION['message']) { echo '<p class="notification">'.$_SESSION['message']).'</p>'; unset($_SESSION['message']); } ?>
So that sums up the index.php file. In the next section, we’ll see how to handle the uploaded file on the server side.
Create the Upload Logic
In the previous section, we created the HTML form which is displayed on the client side and allows you to upload a file from your computer. In this section, we’ll see the server-side counterpart which allows you to handle the uploaded file.
Pull in the code from the upload.php file on GitHub. We’ll go through the important parts of that file.
In the upload.php file, we've checked whether it’s a valid POST request in the first place.
if (isset($_POST['uploadBtn']) && $_POST['uploadBtn'] == 'Upload') { ... }
In PHP, when a file is uploaded, the $_FILES
superglobal variable is populated with all the information about the uploaded file. It’s initialized as an array and may contain the following information for successful file upload.
tmp_name
: The temporary path where the file is uploaded is stored in this variable.name
: The actual name of the file is stored in this variable.size
: Indicates the size of the uploaded file in bytes.type
: Contains the mime type of the uploaded file.error
: If there’s an error during file upload, this variable is populated with the appropriate error message. In the case of successful file upload, it contains 0, which you can compare by using theUPLOAD_ERR_OK
constant.
After validating the POST request, we check that the file upload was successful.
if (isset($_FILES['uploadedFile']) && $_FILES['uploadedFile']['error'] === UPLOAD_ERR_OK) { ... }
You can see that the $_FILES
variable is a multi-dimensional array, the first element is the name of the file field, and the second element has the information about the uploaded file, as we’ve just discussed above.
If the file upload is successful, we initialize a few variables with information about the uploaded file.
// get details of the uploaded file $fileTmpPath = $_FILES['uploadedFile']['tmp_name']; $fileName = $_FILES['uploadedFile']['name']; $fileSize = $_FILES['uploadedFile']['size']; $fileType = $_FILES['uploadedFile']['type']; $fileNameCmps = explode(".", $fileName); $fileExtension = strtolower(end($fileNameCmps));
In the above snippet, we’ve also figured out the extension of the uploaded file and stored it in the $fileExtension
variable.
As the uploaded file may contain spaces and other special characters, it’s better to sanitize the filename, and that’s exactly we’ve done in the following snippet.
$newFileName = md5(time() . $fileName) . '.' . $fileExtension;
It’s important that you restrict the type of file which can be uploaded to certain extensions and don’t allow everything using the upload form. We’ve done that by checking the extension of the uploaded file with a set of extensions that we want to allow for uploading.
$allowedfileExtensions = array('jpg', 'gif', 'png', 'zip', 'txt', 'xls', 'doc'); if (in_array($fileExtension, $allowedfileExtensions)) { ... }
Finally, we use the move_uploaded_file
function to move the uploaded file to the specific location of our choice.
// directory in which the uploaded file will be moved $uploadFileDir = './uploaded_files/'; $dest_path = $uploadFileDir . $newFileName; if(move_uploaded_file($fileTmpPath, $dest_path)) { $message ='File is successfully uploaded.'; } else { $message = 'There was some error moving the file to upload directory. Please make sure the upload directory is writable by web server.'; }
The move_uploaded_file
function takes two arguments. The first argument is the filename of the uploaded file, and the second argument is the destination path where you want to move the file.
Finally, we redirect the user to the index.php file. Also, we set the appropriate message in the session variable, which will be displayed to users after redirection in the index.php file.
How It All Works Together
Don't forget to create the uploaded_files directory and make it writable by the web-server user. Next, go ahead and run the index.php file, which should display the file upload form which looks like this:
Click on the Browse button—that should open a dialog box which allows you to select a file from your computer. Select a file with one of the extensions allowed in our script, and click on the Upload button.
That should submit the form, and if everything goes well, you should see the uploaded file in the uploaded_files directory. You could also try uploading other files with extensions that are not allowed, and check if our script prevents such uploads.
Resolving Common Errors
A lot of things can go wrong during a file upload which might result in errors. You can check the exact error that occurred during the upload using $_FILES['uploadedFile']['error']
. Here is the explanation of those errors:
File is Too Large
UPLOAD_ERR_INI_SIZE
and UPLOAD_ERR_FORM_SIZE
occur when the size of uploaded file is more than the value specified in php.ini or the HTML form respectively. You can get rid of this error by increasing the upload size limits or letting the users know about them beforehand.
Temporary Folder is Missing
UPLOAD_ERR_NO_TMP_DIR
is reported when the temporary folder to upload the file is missing. UPLOAD_ERR_NO_FILE
is reported when there is no file to upload.
Partial Upload or Can't Write to Disk
You will get UPLOAD_ERR_PARTIAL
if the file could only be uploaded partially and UPLOAD_ERR_CANT_WRITE
if the file could not be written to the disk.
A PHP Extension Stopped the File Upload
Sometimes, you will get the error UPLOAD_ERR_EXTENSION
because some extension stopped the file upload. This one will require more investigation by you to figure out which extension caused the problem.
Here is the full code from upload.php which will show users a message on the upload page in case of success or failure of the upload. The information about the success of failure of the upload is stored in the $_SESSION['message']
.
<?php session_start(); $message = ''; if (isset($_POST['uploadBtn']) && $_POST['uploadBtn'] == 'Upload') { if (isset($_FILES['uploadedFile']) && $_FILES['uploadedFile']['error'] === UPLOAD_ERR_OK) { // get details of the uploaded file $fileTmpPath = $_FILES['uploadedFile']['tmp_name']; $fileName = $_FILES['uploadedFile']['name']; $fileSize = $_FILES['uploadedFile']['size']; $fileType = $_FILES['uploadedFile']['type']; $fileNameCmps = explode(".", $fileName); $fileExtension = strtolower(end($fileNameCmps)); // sanitize file-name $newFileName = md5(time() . $fileName) . '.' . $fileExtension; // check if file has one of the following extensions $allowedfileExtensions = array('jpg', 'gif', 'png', 'zip', 'txt', 'xls', 'doc'); if (in_array($fileExtension, $allowedfileExtensions)) { // directory in which the uploaded file will be moved $uploadFileDir = './uploaded_files/'; $dest_path = $uploadFileDir . $newFileName; if(move_uploaded_file($fileTmpPath, $dest_path)) { $message ='File is successfully uploaded.'; } else { $message = 'There was some error moving the file to upload directory. Please make sure the upload directory is writable by web server.'; } } else { $message = 'Upload failed. Allowed file types: ' . implode(',', $allowedfileExtensions); } } else { $message = 'There is some error in the file upload. Please check the following error.<br>'; $message .= 'Error:' . $_FILES['uploadedFile']['error']; } } $_SESSION['message'] = $message; header("Location: index.php");
Learn PHP With a Free Online Course
Today, we discussed the basics of file upload in PHP. In the first half of the article, we discussed the different configuration options that need to be in place for file upload to work. Then we looked at a real-world example which demonstrated how file upload works in PHP.
If you want to learn more PHP, check out our free online course on PHP fundamentals!
In this course, you'll learn the fundamentals of PHP programming. You'll start with the basics, learning how PHP works and writing simple PHP loops and functions. Then you'll build up to coding classes for simple object-oriented programming (OOP). Along the way, you'll learn all the most important skills for writing apps for the web: you'll get a chance to practice responding to GET and POST requests, parsing JSON, authenticating users, and using a MySQL database.
-
FREEPHPPHP Fundamentals
No comments:
Post a Comment