Uploading a file from a web form in PHP is easy. The online manual provides a Handling File Uploads section, and there are several articles on sitepoint.com, including How To Handle File Uploads With PHP by Kevin Yank.

One of the most popular uses is image uploads. Your users can submit photographs from a form without resorting to FTP or other convoluted methods. HTML5 and Flash also permit drag and drop, so the operation is likely to become easier as browsers evolve.

This is where the problems can begin. Camera manufacturers continually brag that they have a larger set of megapixels than their competitors. It’s all rubbish, of course — unless you’re a professional photographer or need to print extremely large images, anything over 4MP is fairly pointless and lens quality is much more important. However, even low-end compacts have 12MP and mobile phones have more than 5MP. The result is that a typical snapshot can easily be 6MB in size.

By default, PHP permits a maximum file upload of 2MB. You can ask users to resize their images before uploading but let’s face it: they won’t. Fortunately, we can increase the limit when necessary.

Two PHP configuration options control the maximum upload size: upload_max_filesize and post_max_size. Both can be set to, say, “10M” for 10 megabyte file sizes.

However, you also need to consider the time it takes to complete an upload. PHP scripts normally time-out after 30 seconds, but a 10MB file would take at least 3 minutes to upload on a healthy broadband connection (remember that upload speeds are typically five times slower than download speeds). In addition, manipulating or saving an uploaded image may also cause script time-outs. We therefore need to set PHP’s max_input_time and max_execution_time to something like 300 (5 minutes specified in seconds).

These options can be set in your server’s php.ini configuration file so that they apply to all your applications. Alternatively, if you’re using Apache, you can configure the settings in your application’s .htaccess file:

php_value upload_max_filesize 10M
php_value post_max_size 10M
php_value max_input_time 300
php_value max_execution_time 300

Finally, you can define the constraints within your PHP application:

ini_set('upload_max_filesize', '10M');
ini_set('post_max_size', '10M');
ini_set('max_input_time', 300);
ini_set('max_execution_time', 300);

PHP also provides a set_time_limit() function so you don’t need to set max_execution_time directly.

Setting the options in your PHP code is possibly more practical, since you can extend the execution time and increase the file size when your application is expecting a large upload. Other forms would revert to the default 30-second time-out and 2MB limit.

Do you have any other tips for uploading large files in PHP?

Tags: configuration, PHP
Craig is a freelance UK web consultant who built his first page for IE2.0 in 1995. Since that time he's been advocating standards, accessibility, and best-practice HTML5 techniques. He's written more than 1,000 articles for SitePoint and you can find him @craigbuckler

  • Mal Curtis

    Execution time is irrelevant, as this happens once PHP is processing the request – whereas the time to upload is communication between the browser and the server software (Apache etc.).

    • http://www.optimalworks.net/ Craig Buckler

      Really? It’s never been irrelevant when I’ve uploaded large images. Even if it were, any manipulation of the image or moving the file could take a while.

      • Salathe

        Perhaps you meant max_input_time rather than (or, as well as) max_execution_time

        max_input_time sets the maximum time, in seconds, the script is allowed to receive input; this includes file uploads. For large or multiple files, or users on slower connections, the default of 60 seconds may be exceeded.

        Source: http://php.net/file-upload.common-pitfalls

      • http://www.optimalworks.net/ Craig Buckler

        Thanks Salathe. That’s interesting — I’ve updated the post accordingly.

      • woodsikov

        I think Mal was saying that the PHP script doesn’t begin executing until after the upload is finished. What is more important is the long period the user is left looking at a screen on which nothing appears to be happening unless you provide some sort of visual feedback, which wasn’t dealt with in your article.

        Also perhaps a http request isn’t the best method for uploading large files – I may need to do this on an upcoming project and would welcome suggestions for alternative methods.

  • Peter Mescalchin

    Mal Curtis is correct, max_input_time is what will need to be increased – the time it takes the browser to push the upload to the server – max_execution_time does not need to be (nor should it) be increased beyond the default of 30 seconds unless in extreme circumstances – and even then I would suggest moving longer processing tasks out of the web request process (e.g. cron/gearman/etc.)
    Another alternative for adjusting the upload_max_filesize/post_max_size/max_input_time values on a per-script folder basis which was introduced with PHP 5.3 are the ‘ini sections’ directives – very handy:
    Handy if you have .htaccess turned off (which I recommend, since it can be quite a slowdown for Apache) and don’t want to resort to ini_set() for the task.

  • Are P

    Large uploads isn’t 10MB, it’s 1Gb or 5Gb. Not so common you say? Well, it depends on the user. Teacher often upload video or whole courses into LMS’s like Moodle. How to upload that large files? You can use jupload.sourceforge.net, it can upload your file in chunks so each upload isn’t more than 1-2MB and then you assemble the file into one at the server side.

  • Sky

    Have you tried this with large files… like 1 Go ?
    Because 10mo or 20mo is ok, but i always have problems wen i try to make this work on large files (understand over 500mo).

    The only solution i have found is to use perl or python with some nifty ajax for a progress bar.

    Its the same things for downloading very large files with a slow adsl connection : after 1 or 2 hours, the server seams to just reject the connection (or PHP dies). The solution for this is a apache mod called x-sendfile (more information here : http://tn123.ath.cx/mod_xsendfile/) that allow’s you to download the file using Apache but doing a callback to a PHP file for the Auth part.

  • markyleong

    To upload files that are larger than your maximum upload_max_filesize and post_max_size, you can use ‘chunked’ uploading. See http://www.plupload.com/ for an example implementation.

  • Luke

    According to the ini_set() documentation, upload_max_filesize can only be set in php.ini or httpd.conf. Also other settings, set by ini_set(), may be to late because of this (post_max_size etc.). PHP handles the post data before your script is even called. Set this settings in php.ini or in .htaccess.

  • http://r.je TomB

    The biggest problem with handling large uploads is not the configuration options, that’s a simple RTFM, but the issue is showing the user how long it’s going to take, which as it stands is not possible using php unfortunately.

    • Tim

      If you have admin access, try the pecl/uploadprogress extension. PHP has the hooks available, the extension to use it though just isn’t enabled as part of the default PHP install for some reason.

      • javadecaf

        Do you know of any good documentation on the PECL/uploadprogress extension? I’m specifically looking for something that would cover implementation, preferably with examples. I tried APC, but I never could get it to work.

  • Tom Dewar

    You may want to consider http://transloadit.com

  • fproof

    I find the uploading of images itself is not the major issue, but the manipulation afterwards. A 2MP photo of 10MB is not a problem to resize, but a 12MP photo of 10MB requires much more memory than available by default. So basically you need to higher the memory limit for PHP processes (which is not always possible in a shared environment). But it’s a bit worrying since cameras keep on producing larger and larger photos and most users just think “the more pixels the better”.
    Someone with an elegant solution to handle this?

    • Thepengwin

      Im watching SWFUpload (http://code.google.com/p/swfupload/) Closely, as it looks like a workable to fix this problem. A planned feature for 2.5 is client-side photo resizing, so it will cut down the image before it is even transmitted, causing less overall uploading time, as well as less processing time and memory usage.

      • fproof

        Interesting. I’ve used swfupload in the past but wasn’t actively following new releases or planned features. So thanks for pointing me to it.

      • Tim

        I used scripts like this once for handling large file uploads (Uploadify, SWFUpload, etc) and apart from the fact they all use Flash to handle the progress bar and uploading, they aren’t fully portable across web servers. I found their behaviour slightly different under IIS vs Apache. The biggest issue being you have to work around Flash not connecting to your PHP sessions.

      • Aleksandar Jovanovic

        SWFUpload is actually only one free I have found so far to have some level of support for sessions. My problem with SWFUpload is that you have to setup a lot of parameters for it just for a simple upload of one file. What I have noticed as a bug is that on some servers progress bar doesn’t move from 0% until upload is done and than just jumps straight to 100% which kind of makes it lose its purpose.

  • jim6917

    Yes, you cannot tell how big the file is until after its uploaded with PHP. Browser security limits our ability to create too-cool scripts. HTML5 is suppose to change this.

  • Rob

    With the exception of max_execution_time, which doesn’t really apply, you can’t set any of those directives in your script: http://us3.php.net/manual/en/ini.list.php.

  • EastCoast

    If the end image finally stored on the server is going to be resized down from the starting photo, using flash player 10 you can load the image direct to memory from the desktop, resize and encode to a jpeg on the client side, then only transfer a low resolution image to the server

  • Sphamandla

    I was reading another article similar to this forgot to bookmark it though. If you ask users to decrease the file size before they upload content the answer is “no” they wont do it,instead they will continue to upload regardless of your request or notification which therefore makes it our job to do the thinking for them because they are not eager on doing that they prefer the don’t make me think approach towards the internet but then again we all do. Good point stated I will keep it in mind in future

  • Martin Fjordvald

    This fails to mention the problem of scalability when uploading files, especially if you’re using pre-fork Apache as your processes will then be occupied for the duration of the upload.

    I wrote a post a response to how it can be solved better using PHP and Nginx here: http://blog.martinfjordvald.com/2010/08/file-uploading-with-php-and-nginx/

  • http://www.idude.net iDude

    The internet is Media Rich with large audio, video and graphic files these days. Many people simply want to upload and post their pictures online without going through the bother of resizing, editing or otherwise messing with it.

    I’ve had to tweak up the max limits for file uploads and page timeouts for a number of projects in PHP, iHTML and ASP. These small tweaks have turned into a little bit of a nuisance. It’s 2010 after all.

    In regards to dealing with resizing of images after upload. I’ll run the image through some code to resize the image down. However, I also programmically apply some sharpening to the image. The amount varies according to final size of the image. How do I or did I come up with the magic numbers to use in programmically sharpen images? Easy, I experimented with a 100 images of all kinds of things, until I found the magic numbers that work best on a whole visually. These numbers sort of vary according to the image libraries/component being used. I really don’t take things further besides automatically resizing the images and sharpen them a little. I’ve made it a point to have “sharpen” as a default check box option they can turn off, because some people upload pictures already correctly sized and sharpened.

    I try to keep web applications simple, instead of trying to build a mini-version of photo shop inside it all.

    I know from years of experience of dealing with Real Estate Agents, Auto Dealers and etc… most of them ain’t going to resize their photos because 80% of them have never laid their hands upon photo editing software.

    This is an area, where it’s best to try to keep things as simple as possible.

  • teo

    Are you sure the upload time counts as execution time of the script???

  • LrgUploading

    Why not avoid all the issues of security and reconfiguring PHP for your server and use a script designed to workaround the issues discussed here? Try using this PHP script called Simple2FTP at Simple2FTP.com

Special Offer
Free course!

Git into it! Bonus course Introduction to Git is yours when you take up a free 14 day SitePoint Premium trial.