Dec/0856
Creating an Upload Progress Bar in PHP with APC
Introduction
In this tutorial I will explain how to create a progress bar for PHP file uploads. There is no method built into PHP for returning the status of an upload in progress, so this requires a module called the Alternative PHP Cache (APC). This allows you to store data across sessions and includes built-in functionality for storing/returning file upload stats.
This tutorial assumes you have some basic understanding of XHTML, PHP, and JavaScript. If you don't, it may be hard to understand.
Installing APC is beyond the scope of this tutorial, so visit the APC Installation page for help or talk to your host. To find out if APC is installed already, create a PHP file on your site containing "<?php phpinfo(); ?>", visit it in your browser, and look for a section titled 'APC.' If it is present, then it is installed.
Similar Posts:
- Saving Time With jQuery
- Toggle Display of Page Elements with JavaScript
- Add Records to a Queue with jQuery
« Previous Next »
Enjoy this article?
Author: Steve
Steve is the owner of UlraMega Tech. He is a freelance Web designer and developer who specializes in PHP and AJAX development.Categories
- General (6)
- News (4)
- Projects (10)
- Lock My Stuff (2)
- TempServers (8)
- Software (7)
- Tips & Tutorials (41)
Archives
- [+]2010 (2)
- [+]2009 (46)
- [+]December (5)
- [+]November (3)
- [+]October (2)
- [+]September (4)
- [+]August (4)
- [+]July (4)
- [+]June (6)
- [+]May (4)
- [+]April (4)
- [+]March (4)
- [+]February (2)
- [+]January (4)
- [+]2008 (15)
- [+]December (14)
- AJAX Loading Image Generator
- Reloading Images Using JavaScript
- Creating a CAPTCHA in PHP with GD
- Bypassing Register_Globals in PHP
- Toggle Display of Page Elements with JavaScript
- What is AJAX?
- WordPress 2.7 Released
- LMS New Feature: Email Form
- Strong Passwords
- ISPConfig - Open Source Web Hosting Panel
- Simple PHP Page Template System
- Creating an Upload Progress Bar in PHP with APC
- Introducing LockMyStuff.com
- About This Blog (WordPress)
- [+]November (1)
- [+]December (14)

February 9th, 2009
Hello,
this the best tutorial about APC upload I have ever seen. Unfortunately, it doesn’t work to me. When I upload file, apc almost immediately return {finish:true;}, therefore file isn’t uploaded yet. I have read about this problem (bug) something, but it is explained very well nowhere. Do you have survey in which cases (server configuration) it happens?
Thank you a lot.
tomasr
February 11th, 2009
Make sure you have this in your PHP configuration to enable upload tracking:
apc.rfc1867 = OnFebruary 13th, 2009
Hello,
this upload bar is excellently working in FF, but I have noticed, that in IE (both 6 and7) it doesn’t work. It just returns error, that object was expected @ line XY (I think it is line with , but it is in IE, so who knows…)
Do you know what I (if it is me) am doing wrong?
Jen
February 13th, 2009
Actually this was an error on my part. When including the script on the page, the type should be text/javascript not application/javascript. I’ve corrected the tutorial to reflect that.
Sorry for the confusion
February 21st, 2009
Yes I’m sure that I’ve apc.rfc1867 = On in php.ini on localhost and production server as well.
I don’t know why it doesn’t work on localhost. Only one reason, why it doesn’t work on production servver is that php is there compiled like fastcgi and I’ve ever read, that in this case apc doesn’t work.
Any idea?
February 23rd, 2009
I can’t find any information on any configuration that would cause that. It’s probably something in your script.
February 26th, 2009
http://www.ibm.com/developerworks/opensource/library/os-php-v525/index.html
IBM recommends “Using a text editor, open /php/php.ini and add the line apc.rfc1867 = on (it doesn’t matter where). If you’re trying to test locally and plan to upload large files so you can actually see progress, you’ll also want to add the following directives: apc.max_file_size = 200M, upload_max_filesize = 200M, and post_max_size = 200M. Don’t do this on a live production server, though, or you’re likely to use up bandwidth and disk space allotments, not to mention slowing everyone else down to a crawl.” <- WAMP
for localhost tests. I dont know if this will help or not.
March 7th, 2009
I am completely lsot this about about the most amazing tutorial I have ever seen yet for some reason i cannot get it working.
I want to use this script for uploading videos to a website i am building but cant get a local demo running for the life of me!!!!
Any Ideas????
http://fadetoclear.com/uploader/upload_form.php
March 9th, 2009
hi!
it works with multiple uploads?
i would like to upload 3 files at time.
March 9th, 2009
Yes, it should work fine with multiple files. Just add more files fields to the form and name them
file[]so PHP will treat them as an array. There is an example showing how to handle multiple files at: http://www.php.net/manual/function.move-uploaded-file.php#function.move-uploaded-file.examplesMarch 18th, 2009
Thanks for a very useful tutorial. I truly appreciate it.
In case this will help others in the future. I had to change
from $_FILES['userfile']['name'] to $_FILES['file']['name']
and from $_FILES['userfile']['tmp_name'] to $_FILES['file']['tmp_name']
in order for the code to work.
March 18th, 2009
Good catch! I corrected the tutorial. Copy/paste error…
June 29th, 2009
Thanks for the tutorial. Works excellent!!!!
How do i make the progress bar uploading to be done in a separate window? and when i try uploading files of larger size i get a division by zero warning and the progress bar stops working. Could you please help me out with these two issues.
July 27th, 2009
I think the easiest way to use a separate window is to load the upload form in a separate window, and it should work just fine. Otherwise, you can add some JavaScript to the startProgress function to pop open a new window.
The division by zero can be caused by a number of things. Maybe your PHP configuration has the apc.max_file_size, upload_max_filesize, or post_max_size set too low to allow your large files.
July 27th, 2009
Hi
I am using above exaple but in my code apc_fetch function is not working.
php.ini file setting is as below:
apc.enable_cli Off Off
apc.enabled On On
apc.file_update_protection 2 2
apc.filters no value no value
apc.gc_ttl 3600 3600
apc.include_once_override Off Off
apc.max_file_size 40M 40M
apc.mmap_file_mask no value no value
apc.num_files_hint 1000 1000
apc.report_autofilter Off Off
apc.rfc1867 On On
apc.rfc1867_freq 0 0
apc.rfc1867_name APC_UPLOAD_PROGRESS APC_UPLOAD_PROGRESS
apc.rfc1867_prefix upload_ upload_
apc.shm_segments 1 1
apc.shm_size 30 30
apc.slam_defense 0 0
apc.stat On On
apc.stat_ctime Off Off
apc.ttl 0 0
apc.user_entries_hint 4096 4096
apc.user_ttl 0 0
Please help me to sort out this.I think $status['total'] is not working. Guide me what changes I have to do?
July 27th, 2009
What version of PHP are you using? The upload tracking requires that APC is compiled against 5.2 or later. Other than that, I don’t see anything wrong with that configuration.
August 17th, 2009
No matter what I do, I cannot get apc to work. It is sooo troublesome. Im very frustrated. I set that rfc on, and enabled apc. yet, it isn’t working. What happens is when I upload a file, the file gets uploaded, but the stat doesnt change. the progress bar doesnt load, and it says “upload complete”.
This is what my phpinfo says:
apc
APC Support enabled
Version 3.0.19
MMAP Support Enabled
MMAP File Mask no value
Locking type pthread mutex Locks
Revision $Revision: 3.154.2.5 $
Build Date Aug 15 2009 09:40:40
Directive Local Value Master Value
apc.cache_by_default On On
apc.coredump_unmap Off Off
apc.enable_cli Off Off
apc.enabled On On
apc.file_update_protection 2 2
apc.filters no value no value
apc.gc_ttl 3600 3600
apc.include_once_override Off Off
apc.max_file_size 10M 10M
apc.mmap_file_mask no value no value
apc.num_files_hint 1000 1000
apc.report_autofilter Off Off
apc.rfc1867 On On
apc.rfc1867_freq 0 0
apc.rfc1867_name APC_UPLOAD_PROGRESS APC_UPLOAD_PROGRESS
apc.rfc1867_prefix upload_ upload_
apc.shm_segments 1 1
apc.shm_size 30 30
apc.slam_defense 0 0
apc.stat On On
apc.stat_ctime Off Off
apc.ttl 0 0
apc.user_entries_hint 4096 4096
apc.user_ttl 0 0
apc.write_lock On On
PLEEEASE HELP ME! what am I doing wrong?
August 20th, 2009
code is not working. apc is enable but
when I upload a file, the file gets uploaded, but the stat doesnt change. the progress bar doesnt load, and it says “upload complete”.Please help me. apc configuration is as follows
pc.cache_by_default On On
apc.coredump_unmap Off Off
apc.enable_cli On On
apc.enabled On On
apc.file_update_protection 2 2
apc.filters no value no value
apc.gc_ttl 3600 3600
apc.include_once_override Off Off
apc.max_file_size 40M 40M
apc.mmap_file_mask /tmp/apc.gkjMYq /tmp/apc.gkjMYq
apc.num_files_hint 1024 1024
apc.report_autofilter Off Off
apc.rfc1867 On On
apc.rfc1867_freq 0 0
apc.rfc1867_name APC_UPLOAD_PROGRESS APC_UPLOAD_PROGRESS
apc.rfc1867_prefix upload_ upload_
apc.shm_segments 1 1
apc.shm_size 128M 128M
apc.slam_defense 0 0
apc.stat On On
apc.stat_ctime Off Off
apc.ttl 7200 7200
apc.user_entries_hint 4096 4096
apc.user_ttl 7200 7200
apc.write_lock On On
August 20th, 2009
Code is not working . when I upload a file, the file gets uploaded, but the stat doesnt change. the progress bar doesnt load, and it says “upload complete”.Please help me. apc configuration is as follows
pc.cache_by_default On On
apc.coredump_unmap Off Off
apc.enable_cli On On
apc.enabled On On
apc.file_update_protection 2 2
apc.filters no value no value
apc.gc_ttl 3600 3600
apc.include_once_override Off Off
apc.max_file_size 40M 40M
apc.mmap_file_mask /tmp/apc.gkjMYq /tmp/apc.gkjMYq
apc.num_files_hint 1024 1024
apc.report_autofilter Off Off
apc.rfc1867 On On
apc.rfc1867_freq 0 0
apc.rfc1867_name APC_UPLOAD_PROGRESS APC_UPLOAD_PROGRESS
apc.rfc1867_prefix upload_ upload_
apc.shm_segments 1 1
apc.shm_size 128M 128M
apc.slam_defense 0 0
apc.stat On On
apc.stat_ctime Off Off
apc.ttl 7200 7200
apc.user_entries_hint 4096 4096
apc.user_ttl 7200 7200
apc.write_lock On On
August 20th, 2009
APC installation and configuration are beyond the scope of this tutorial. You may want to look at the uploadprogress PECL extension (http://pecl.php.net/package/uploadprogress) as an alternative to APC.
August 30th, 2009
Thank you so much for this script i m using IIS 6 and php 5.2 on win xp sp3
I ve tried so many scripts to show progress bar but i ve failed until use your script.It s working and showing bar and % without any problem.One minor problem is about ff.First it shows the bar and progress but when i refresh it doesn t show anything.I think it s about cache.When i closed and open again ff, it shows bar first time but doesn t show anythinh second time.Any idea?
Note: i ve used php as a Cgi then i changed it to Isapi today,now everything is fine.
August 31st, 2009
one more thing that i ve realised just know is the uploaded data isnt send to upload.php
Apc functions and progress bar works correctly,probably uploaded data is send to temporary folder,any idea about why doesn t uploaded data sent to upload.php?
August 31st, 2009
i changed $path .= basename($_FILES['file']['name']); to
$path =$path.basename($_FILES['file']['name']);
——-
$path = ‘temp/’;
$path =$path.basename($_FILES['file']['name']);
if(move_uploaded_file($_FILES['file']['tmp_name'], $path)){
and added echo ““.$path.”“.
” succes”;
echo “$target_path“;
}
else{
echo “Dosya göndeilemedi!”;
}
now uploaded data is sent to upload.php and file save to folder which is referred to “temp/ ” inside upload.php.
but if the file bigger than 15mb the upload bar instantly goes to %100
post_max=200m
upload_size=200m
apc.max_file_size=200m
August 31st, 2009
Hi I’m hoping that someone can help me out. When I goto info.php there is a APC section that currently has apc.rfc1867 set to OFF and apc.max_file_size is set to 1M apc.enabled is set to ON.
This is the location to where the php.ini file is located: /etc/php5/apache2/php.ini
The problem is when I open php.ini to edit it, there is mention to ( apc) at all.
Can anyone help me?
Thank you.
August 31st, 2009
Just add this somewhere in the fle:
[apc]apc.rfc1867 = On
August 31st, 2009
Thank you Steve for such a great script and for your help.
I recently downloaded Ubuntu 9.04 cause I didn’t like the new Mandriva version, and I decided to use it as a server so friends can connect to me and download and upload files. The problem was when they uploaded something There Progress Bar would be at 100% while the upload wasn’t finished yet.
So I went on a search for a .php upload with progress bar and ended up here.
Thank you once again. and for your quick fix reply.
August 31st, 2009
hey steve i have last one question.When i upload a file that bigger than 20mb,bar goes to %100 instantly,but upload s still going then it finish without any problem here is my php.ini.I m using IE 7 and IIS 6.Is is about IIS or apc configs?
post_max=200m
upload_size=200m
apc.max_file_size=200m
apc.rfc1867 = on
apc.enabled=1
September 1st, 2009
i solved it.Who want to send files about 100M need to set :
function startProgress(uid)
………..
setTimeout(‘getProgress(“‘ + uid + ‘”)’, 1000);
1000(ms) to 3000-8000 (ms).
I think it s depends on how many ram the server machine have.
September 2nd, 2009
Hi Steve.
This is a great tutorial so far I found on website, thanks. One problem I have is that
I installed APC and configured everything, when i upload file, the progress bar just show 100% complete on FF browser. I first thought of the upload file size is too small than I changed to large file size but it still showed the same. I then put an alert message in the Ajax function to check the “progress” returned from responsetext, it shows the 100% only once. Where could be the problem?
Thank you,
September 2nd, 2009
Try increasing the timeout in the startProgress JS function. It worked for the previous poster.
Let me know if it works so I can update the tutorial.
September 2nd, 2009
Thanks for reply – it didn’t work for me. The progress bar doesn’t show percentage of completion, it only shows “Upload Complete” at the end. File is uploaded to a temp directory. I will double check the ajax part.
September 2nd, 2009
I think I might find the problem by putting debug message in the ajax code in the request object status and responseText, and hardcode a return value in getprogress.php, then the percentage showed, and the setTimeout triggered. It seems like the return value always be 100 from getprogress.php, and that is I was getting the “Upload Complete” all the time, why is it? Could it related to cache problem? I did put the header expire code in it like the sample code.
September 2nd, 2009
if you use php-cgi ,you should change it to isapi,it is known that php-cgi has a problem with apc extension.
September 3rd, 2009
Thank you for reply – but how to change to isapi exactly? thanks
September 3rd, 2009
do you use IIS or apache as a web server?
September 3rd, 2009
I am using Apache 2.0.63.
September 3rd, 2009
here is how to use mod_isapi for apache
http://httpd.apache.org/docs/2.0/mod/mod_isapi.html.
You should also set apc configuration in php.ini.
Try big files about 100-110mb.
I use this code on windows xp sp3-IIS 5.1 machine and Windows 7-Apache installed machine.Both work.
September 3rd, 2009
Hey steve,how can i show to user uploaded file name and total file size when progress bar seems on screen?
September 4th, 2009
In getprogress.php,
$statuscontains an array of file information.$status['total']is the file size in bytes, and$status['filename']is the name of the file. Other values are current (bytes uploaded), rate (upload speed B/s), name (variable name), temp_filename (temporary file location), cancel_upload (1 if upload is cancelled), done (1 if upload is complete).Basically, you can have getprogress.php return some JSON and parse the different values within JavaScript. You can simply return the whole array like this:
Then your JavaScript for getProgress() will look something like this:
That should give you the same result as before, but now you can access all the pieces of data about the file from the
progressobject. So you can insert the value ofprogress.total,progress.filename, or evenprogress.rateanywhere on the page.Hope this helps!
September 5th, 2009
Sorry, but after change all this, progress bar doesn t move.
September 5th, 2009
Here is a working example you can look at: http://www.ultramegatech.com/blog/examples/pb2/upload_form.php Just look at the source to see how it works. Also note that json_encode is available on PHP 5.2+. Otherwise you’ll need to manually produce the JSON.
I also added rounding for the percentage so you get an even number.
September 5th, 2009
Hey Steve I’m sorry to bother you further but I was wondering based on that example site, Is it possible to display an estimate time for download that will refresh it’s figures appropriately?
September 5th, 2009
It seems like the transfer rate only appears when the upload is complete, so I don’t know if that’s possible unfortunately. Otherwise you would divide the filesize (subtract current if you want time remaining) by the rate to get the number of seconds.
September 6th, 2009
sorry but I’m really new to .php
would that be:
var progress = eval(‘(‘+HttpRequestObject.responseText+’)');
var percent = Math.round(progress.current/progress.total*100);
+ var TimeRemaning = Math.round(progress.total/progress.current); +
document.getElementById(‘filename’).innerHTML = progress.filename;
document.getElementById(‘filesize’).innerHTML = progress.total;
document.getElementById(‘current’).innerHTML = progress.current
+ document.getElementByld(‘TimeRemaning’).innerHTML = progress.TimeRemaining +
I really kind of feel bad to bother you, but I guess you had to expect morons like me to come along and wish you never bothered to post such a fine script to begin with.
September 6th, 2009
Assuming you have access to the rate value during upload, you would get the number of seconds remaining with:
Anyway, this relies on APC to return the transfer rate during upload. Otherwise you’ll have to figure out a way to estimate the rate within JavaScript.
September 6th, 2009
document.getElementById(‘remain’).innerHTML = (progress.total/progress.current);
and add
…..
Remain: sec
September 9th, 2009
i got installation problem in APC.After i installed and put extension=”apc.so”. in php.ini it shows following error
Warning: PHP Startup: It is not safe to rely on the system’s timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected ‘America/Halifax’ for ‘-4.0/no DST’ instead in Unknown on line 0
but i mentioned timezone in php.ini,any one can help me
September 14th, 2009
Great tutorial! Its exactly what I need. Unfortunately I’m stuck and cant seem to figure out the problem. First I tried a 1.3 Mb file which worked fine but since I am doing it all locally, the bar immediately went to 100%. Then I tried a larger file (around 10 Mb) but the bar never makes any progress and instead displays “Upload Complete” with Upload inside the left side of the bar and Complete underneath the bar.
phpinfo() shows apc installed with rfc1867 and max file size of 200M. I also made sure isapi_module was selected in Apache on wamp. Can anyone help me out?
September 14th, 2009
function startProgress(uid)
………..
setTimeout(’getProgress(”‘ + uid + ‘”)’, 1000);
change 1000(ms) to 3000-8000 (ms).
try this.
September 14th, 2009
hey steve,do know any host that i can install and use apc extension?
September 17th, 2009
Sorry, I don’t know of any hosts that allow that kind of access. You’ll need to find a host that has APC installed, get a VPS or server, or use another progress bar solution.
September 16th, 2009
Can it work with mod_security? If I enabled it, it don’t works, but in the mod_sec logs, I don’t see anything.
September 17th, 2009
Sorry, I don’t know anything about mod_security.
September 17th, 2009
Hi Steve,
I really appreciate your tutorial and the example works fine on my local test server. Unfortunately the webmaster of our site decided only to allow access to any page using “index.php?site=webpage” where the target file is located in a subfolder like “/webpage/webpage.php”. While the upload still works for itself, no information about the progress is received. I reckon it’s because of the following code line:
HttpRequestObject.open(‘GET’, ‘index.php?site=getprogress&uid=’ + uid, true);
Is there any way to include getprogress.php into upload_form.php? In case not, how can the uid be passed to getprogress.php properly?
September 17th, 2009
That looks like it should work just fine. I guess I’ll need more information about the setup to know what’s going wrong.
October 6th, 2009
let progress bar work -
<input type="hidden"
must be BEFORE
<input type="file"