- 3 Ways to Upload Large Files in PHP (Settings, Chunking, Resumable)
- TABLE OF CONTENTS
- LARGE UPLOADS IN PHP
- METHOD 1) TWEAK PHP SETTINGS
- 1A) UPDATE PHP.INI
- 1B) UPDATING THE HTACCESS FILE
- 1C) UPLOAD!
- 1D) INI SET?
- METHOD 2) CHUNK UPLOAD
- 2A) HTML & JAVASCRIPT
- 2B) SERVER-SIDE UPLOAD HANDLER
- METHOD 3) RESUMABLE UPLOAD
- 3A) HTML & JAVASCRIPT
- 3B) DOWNLOAD FLOW PHP SERVER
- 3C) FLOW PHP UPLOAD HANDLER
- DOWNLOAD & NOTES
- SUPPORT
- EXAMPLE CODE DOWNLOAD
- EXTRA BITS & LINKS
- FILE TYPE RESTRICTIONS
- LINKS & REFERENCES
- YOUTUBE TUTORIAL
- THE END
- PHP File Upload
- Configure The «php.ini» File
- Create The HTML Form
- Create The Upload File PHP Script
- Check if File Already Exists
- Limit File Size
- Limit File Type
- Complete Upload File PHP Script
- Complete PHP Filesystem Reference
3 Ways to Upload Large Files in PHP (Settings, Chunking, Resumable)
Welcome to a tutorial on how to upload large files in PHP. Once upon a time in the Stone Age of the Internet, uploads were manageable without large files. But these days, we have to deal with all kinds of oversized files, and the “traditional” upload mechanism just can’t handle it.
To deal with large uploads in PHP, there are a few possible alternatives:
- Change the upload_max_filesize limit in php.ini.
- Split and upload the file in smaller chunks, and assemble them when the upload is complete.
- Implement resumable uploads.
But just how does each of these methods work? Read on for the examples!
TABLE OF CONTENTS
LARGE UPLOADS IN PHP
All right, let us now get into the examples and possible ways of handling large uploads in PHP.
METHOD 1) TWEAK PHP SETTINGS
1A) UPDATE PHP.INI
upload_max_filesize = 150M post_max_size = 150M max_input_time = 300 max_execution_time = 300
- upload_max_filesize – The maximum allowed upload file size.
- post_max_size – The maximum allowed POST data size.
- max_input_time – Maximum allowed input time.
- max_execution_time – Maximum allowed time the scripts are allowed to run.
But of course, I will not recommend changing the php.ini file directly. This will affect the entire server and all your other websites as well.
1B) UPDATING THE HTACCESS FILE
php_value upload_max_filesize 150M php_value post_max_size 150M php_value max_input_time 300 php_value max_execution_time 300
If you don’t have access to php.ini , or just want to apply the settings for a single site – It is also possible to change the settings by creating a .htaccess file. IIS and NGINX users, you will need to do some of your own research.
1C) UPLOAD!
Well, this is just a regular upload form. For those who may have missed out on basic file upload.
1D) INI SET?
For you guys who are thinking of using ini_set() to change the upload size – Take note that according to the official core php.ini directives, upload_max_filesize is only changeable in PHP_INI_PERDIR . Meaning, it can only be tweaked in the php.ini or .htaccess file; ini_set(«upload_max_filesize», «150M») will not work.
METHOD 2) CHUNK UPLOAD
2A) HTML & JAVASCRIPT
This second method is called “chunking” – Splitting a large file and uploading them in smaller chunks. While it may sound difficult, there is thankfully an open-source library called Plupload that we can use. This is pretty much a modified version of the “default Plupload” demo script.
- There are only 2 HTML elements here.
- Upload file list and progress.
- Click to pick files for upload.
- Captain Obvious. Load Plupload from the CDN.
- Initiate Plupload on page load. Not going to explain line by line, but this basically starts the upload immediately after choosing a file.
That is the gist of it, read the official documentation (links in the extra section below) if you need more customizations.
2B) SERVER-SIDE UPLOAD HANDLER
exit(json_encode(["ok"=>$ok, "info"=>$info])); > // (B) INVALID UPLOAD if (empty($_FILES) || $_FILES["file"]["error"]) < verbose(0, "Failed to move uploaded file."); >// (C) UPLOAD DESTINATION - CHANGE FOLDER IF REQUIRED! $filePath = __DIR__ . DIRECTORY_SEPARATOR . "uploads"; if (!file_exists($filePath)) < if (!mkdir($filePath, 0777, true)) < verbose(0, "Failed to create $filePath"); >> $fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : $_FILES["file"]["name"]; $filePath = $filePath . DIRECTORY_SEPARATOR . $fileName; // (D) DEAL WITH CHUNKS $chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0; $chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0; $out = @fopen(".part", $chunk == 0 ? "wb" : "ab"); if ($out) < $in = @fopen($_FILES["file"]["tmp_name"], "rb"); if ($in) < while ($buff = fread($in, 4096)) < fwrite($out, $buff); >> else < verbose(0, "Failed to open input stream"); >@fclose($in); @fclose($out); @unlink($_FILES["file"]["tmp_name"]); > else < verbose(0, "Failed to open output stream"); >// (E) CHECK IF FILE HAS BEEN UPLOADED if (!$chunks || $chunk == $chunks - 1) < rename(".part", $filePath); > verbose(1, "Upload OK");
Once again, this is pretty much a modified version of the demo upload handler. Not going to explain line-by-line, but how this works essentially:
- Create an empty .part file on the first chunk.
- Append chunks into the .part file as they are being uploaded.
- When all the chunks are assembled, rename the .part file back to what it’s supposed to be.
Done! You now have a system that is capable of handling large file uploads.
METHOD 3) RESUMABLE UPLOAD
3A) HTML & JAVASCRIPT
You should be familiar with this last method – Resumable uploads. Yep, not going to reinvent the wheel. Using FlowJS here to drive the resumable upload.
- The HTML only has 3 elements.
- Upload file list.
- Upload button.
- Pause/resume button.
- Load the FlowJS library.
- Initiate FlowJS, not going to run through line-by-line again. But just like Plupload, this starts uploading once a file is selected. Read their documentation if you want the full list of settings and events. Links below.
3B) DOWNLOAD FLOW PHP SERVER
- Download and install Composer if you have not done so.
- Open the command line, navigate to your project folder.
- Run composer require flowjs/flow-php-server .
That’s all. Composer will fetch the latest version into the vendor/ folder.
3C) FLOW PHP UPLOAD HANDLER
setTempDir(__DIR__ . DIRECTORY_SEPARATOR . "temp"); $request = new \Flow\Request(); // (B) HANDLE UPLOAD $uploadFolder = __DIR__ . DIRECTORY_SEPARATOR . "uploads" . DIRECTORY_SEPARATOR; $uploadFileName = uniqid() . "_" . $request->getFileName(); $uploadPath = $uploadFolder . $uploadFileName; if (\Flow\Basic::save($uploadPath, $config, $request)) < // File saved successfully >else < // Not final chunk or invalid request. Continue to upload. >
Just a small modified version of the official demo once again. Probably shouldn’t use this as-it-is, but a good start nonetheless.
DOWNLOAD & NOTES
Here is the download link to the example code, so you don’t have to copy-paste everything.
SUPPORT
600+ free tutorials & projects on Code Boxx and still growing. I insist on not turning Code Boxx into a «paid scripts and courses» business, so every little bit of support helps.
EXAMPLE CODE DOWNLOAD
Click here for the source code on GitHub gist, just click on “download zip” or do a git clone. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
EXTRA BITS & LINKS
That’s it for all the upload methods, and here is a section of small extras and links that may be useful to you.
FILE TYPE RESTRICTIONS
All the above examples now accept all kinds of files and extensions. If you want to restrict the file types, I will highly recommend doing a simple server-side check instead.
LINKS & REFERENCES
- File upload directives in php.ini
- Official documentation for Plupload
- Flow JS
- FlowJS – GitHub
- Flow PHP Server – GitHub
- CDNJS
- Official Website
- GitHub
- CDNJS
YOUTUBE TUTORIAL
THE END
Thank you for reading, and we have come to the end of this short tutorial. I hope that it has helped to solve your big upload woes. If you have stuff you like to add to this guide, please feel free to comment below. Good luck and happy coding!
PHP File Upload
However, with ease comes danger, so always be careful when allowing file uploads!
Configure The «php.ini» File
First, ensure that PHP is configured to allow file uploads.
In your «php.ini» file, search for the file_uploads directive, and set it to On:
Create The HTML Form
Next, create an HTML form that allow users to choose the image file they want to upload:
Some rules to follow for the HTML form above:
- Make sure that the form uses method=»post»
- The form also needs the following attribute: enctype=»multipart/form-data». It specifies which content-type to use when submitting the form
Without the requirements above, the file upload will not work.
- The type=»file» attribute of the tag shows the input field as a file-select control, with a «Browse» button next to the input control
The form above sends data to a file called «upload.php», which we will create next.
Create The Upload File PHP Script
The «upload.php» file contains the code for uploading a file:
$target_dir = «uploads/»;
$target_file = $target_dir . basename($_FILES[«fileToUpload»][«name»]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// Check if image file is a actual image or fake image
if(isset($_POST[«submit»])) $check = getimagesize($_FILES[«fileToUpload»][«tmp_name»]);
if($check !== false) echo «File is an image — » . $check[«mime»] . «.»;
$uploadOk = 1;
> else echo «File is not an image.»;
$uploadOk = 0;
>
>
?>?php- $target_dir = «uploads/» — specifies the directory where the file is going to be placed
- $target_file specifies the path of the file to be uploaded
- $uploadOk=1 is not used yet (will be used later)
- $imageFileType holds the file extension of the file (in lower case)
- Next, check if the image file is an actual image or a fake image
Note: You will need to create a new directory called «uploads» in the directory where «upload.php» file resides. The uploaded files will be saved there.
Check if File Already Exists
Now we can add some restrictions.
First, we will check if the file already exists in the «uploads» folder. If it does, an error message is displayed, and $uploadOk is set to 0:
// Check if file already exists
if (file_exists($target_file)) echo «Sorry, file already exists.»;
$uploadOk = 0;
>Limit File Size
The file input field in our HTML form above is named «fileToUpload».
Now, we want to check the size of the file. If the file is larger than 500KB, an error message is displayed, and $uploadOk is set to 0:
// Check file size
if ($_FILES[«fileToUpload»][«size»] > 500000) echo «Sorry, your file is too large.»;
$uploadOk = 0;
>Limit File Type
The code below only allows users to upload JPG, JPEG, PNG, and GIF files. All other file types gives an error message before setting $uploadOk to 0:
Complete Upload File PHP Script
The complete «upload.php» file now looks like this:
$target_dir = «uploads/»;
$target_file = $target_dir . basename($_FILES[«fileToUpload»][«name»]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));?php
// Check if image file is a actual image or fake image
if(isset($_POST[«submit»])) $check = getimagesize($_FILES[«fileToUpload»][«tmp_name»]);
if($check !== false) echo «File is an image — » . $check[«mime»] . «.»;
$uploadOk = 1;
> else echo «File is not an image.»;
$uploadOk = 0;
>
>// Check if file already exists
if (file_exists($target_file)) echo «Sorry, file already exists.»;
$uploadOk = 0;
>// Check file size
if ($_FILES[«fileToUpload»][«size»] > 500000) echo «Sorry, your file is too large.»;
$uploadOk = 0;
>// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) echo «Sorry, your file was not uploaded.»;
// if everything is ok, try to upload file
> else if (move_uploaded_file($_FILES[«fileToUpload»][«tmp_name»], $target_file)) echo «The file «. htmlspecialchars( basename( $_FILES[«fileToUpload»][«name»])). » has been uploaded.»;
> else echo «Sorry, there was an error uploading your file.»;
>
>
?>Complete PHP Filesystem Reference
For a complete reference of filesystem functions, go to our complete PHP Filesystem Reference.