tl;dr version at bottom.
A long time ago, when I pondered of good settings to allow large file uploads for PHP, I naturally searched Google. I blindly followed at the time. How could I have known better? There were millions of bad advices! But now I know better. And so in hopes to offset the balance even just a teeny tiny bit, I blog.
But before I start, I would like to note that PHP, by nature as of now (PHP5.x), is not a very good foundation for large uploads. Alternative means such as flash uploads are much more apted for this as they can have consistent 2 way communication whereas PHP cannot.
There are three main settings that affect how much a user can upload in PHP. max_input_time, upload_max_filesize and post_max_size.
Max Input Time
Max input time is how long it takes to parse GET and POST in seconds. This is not how long it takes to upload, it’s how long it takes for the OS to handle the file. To give an analogy, think of extracting from a zip file, you see the zip file extract than your windows moves it again. lol It’s like the 2nd part. 30 seconds is usually plenty unless you have a slow disk/processor. You can raise if you like. But a file parsing for over 30 seconds also means that you’re disrupting every other service greatly.
Here’s what it says in PHP docs.
This sets the maximum time in seconds a script is allowed to parse input data, like POST and GET. It is measured from the moment of receiving all data on the server to the start of script execution.
Ironically, the PHP pitfalls page conflicts with the docs stating that it includes uploading time. However, testing shows the documentation is correct and it only counts for parsing the data.
max_input_time = 30
Upload Max File Size:
This setting is pretty straight forward. The maximum size you want to allow for the upload. If you want maximum of 100MB, you write 100M.
Link to docs: http://php.net/manual/en/ini.core.php#ini.upload-max-filesize
upload_max_filesize = 100M
Post Max Size
As file uploads are always done in POST, we also need to increase the maximum POST size. Technically, we also need to account for upload file size in addition to other POST data. But since other POST data is likely to be less than a single kilobyte, it drowns out in lack of precision.
Link to docs: http://php.net/manual/en/ini.core.php#ini.post-max-size
post_max_size = 100M
Bad Advices on the Net
Now these are the bad advices commonly found on the net regarding PHP upload. Tutorials often tell you to increase these to allow large file uploads. But they’re unrelated.
Max Execution Time
Despite millions of tutorials out there that tells you to increase max execution time for this, you do not need to… /facepalm. They’re just people following other people’s advices without checking if it’s true. Max execution time has no relevance to file uploads unless your PHP attempts to do something with that uploaded file which takes time. For example, your PHP tries to do a rolling hash on the file and the hashing process takes 60 seconds because the file is enormous.
memory_limit is again, not important UNLESS the exception mentioned above applies.
1 2 3
max_input_time = 30 ; number in seconds to PARSE input - not upload. upload_max_filesize = 100M ; amount of upload you want to allow. 100MB in this example post_max_size = 100M ; ditto
That’s all folks! And hopefully you stop following bad advices. 🙂
Pingback: PHP: Upload/import of large csv files, server resource limitations, php.ini | linux-blog – Fa. anracon – Dr. Mönchmeyer
Just what i have been looking for…. Just to clarify… Am i right in thinking that although my members could be uploading files in excess of 150mb… i would just need to set my upload_max_filesize limit to say 200M and then post_max_size to 200M to replicate.. EVEN if they did have a super slow connection.
max_input_time would be fine to stay at 30?
Normally, if they’re having to deal with timeout issues while uploading from slow connection, you may wish to review your webserver (apache, nginx, etc) settings and not the PHP settings. However, if you use apc.rfc1867, it may change the behavior as it brings the data transfer progress down to the PHP layer which normally doesn’t happen at all. But I don’t have the test data for that to recommend in any direction if you are using that.