How to create a php upload progress meter
By Justin Silverton
This progess meter is based on the yahoo user interface library and alternative php cache (APC). You will need both of these for it to display properly. PHP 5.2.0 or higher is also required. (I have written a previous article on alternative PHP cache here).
The yahoo user interface library can be found here.
How it works
Once APC is installed and configured, the following needs to be added to your php.ini:
apc.rfc1867 = on
Aside from the Yahoo libraries, this is what makes the progress meter possible using php.
This is called the File Upload Progress hook handler and it is only available
if you compiled APC against PHP 5.2.0 or later. When enabled
any file uploads which includes a field calledÂ
APC_UPLOAD_PROGRESS before the file field in an upload form
will cause APC to automatically create an upload_
user cache entry where is the value of the APC_UPLOAD_PROGRESS form entry.

Download
Demo can be found here
Source can be found here
58 Comments so far
Leave a reply






Very cool, wish I had PHP 5 to play with, my host is sticking with 4 though for now unfortunately.
Surely there is a “better” way to do it for previous versions?
I.e. using ajax to upload the file itself or use a callback?
[…] This tool is create d with all of Yahoo new gui tools. GO Check it out!read more | digg story Share and Enjoy:These icons link to social bookmarking sites where readers can share and discover new web pages. […]
I’ve installed PHP 5.2.0 as a FastCGI server API, and tried your example but APC returns false for every AJAX request. Is this only available when PHP installed as Apache module?
I think this is a bug with the APC libraries. I looked it up and found info on the bug here:
http://pecl.php.net/bugs/bug.php?id=8575&edit=1
You might want to try running it as a module instead.
Thanks, I’ll see the link, I’ve installed uploadprogress extension which was released for php 5.2.0 from PECL, It works just fine. Only needs some cache mangament headers to work in IE.
Hi
Der Fehler muss also irgenwo in der Win-Registrierung liegen.
Hat jemand ne Idee wo ich suchen muss ?
Bye
Merry Chrismast, Justin.
I am newbie on PHP.
Could you please give us PHP code example for handling single or multiple file upload using your progress bar?
I am trying several times using code on PHP Manual but still no luck.
foreach ($_FILES[”pictures”][”error”] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$tmp_name = $_FILES[”pictures”][”tmp_name”][$key];
$name = $_FILES[”pictures”][”name”][$key];
move_uploaded_file($tmp_name, “data/$name”);
}
}
Thank you.
Thanks Anton,
You might want to first try downloading the source example here: http://progphp.com/progress.phps
This will show you how to handle file uploads.
Hi I got the demo to work and it works really well but i am wondering where the uploading part happens in the demo. To me it looks like it is just uploaded but never moved to a permanent location. Can somebody help me out?
This should move it to a permanent location:
$uploaddir = ‘’; //put your permanent directory path here
$uploadfile = $uploaddir . basename($_FILES[’upload_form’][’name’]);// you might have to add a name=upload_form tag to the form in the demo
//make sure the directory you are copying this file to has proper write permissions
move_uploaded_file($_FILES[’userfile’][’tmp_name’],$uploadfile);
where do i place this code?
ok so i figured out where to put the move_uploaded_file. Now how can i make it upload multiple files?
Javis,
Here is an example I found that allows multiple file upload using DOM tricks.
http://the-stickman.com/web-development/javascript/upload-multiple-files-with-a-single-file-element/
[…] das müsste mit den neusten PHP Versionen auch gehen! PHP: Handling file uploads - Manual (siehe unten in den Kommentaren, mal nach "progress" suchen auf der Seite). Das sieht ganz nett aus: Jaslabs: High performance php » How to create a php upload progress meter Hier noch was ausm Pear: HTML_Progress2 - PEAR Open Source PHP OO Progress Meter __________________ Bitte keine PN’s - schreibt mir ne anständige Mail oder sprecht mich über Msn / Icq an Milian Wolff | html2text.php | 3co […]
thanks for posting this… good stuff. however my host cannot use apc for some reason… has anyone had any luck using the uploadprogress extension by christian stocker? it’s available on pecl.
blessings…
if anyone is interested in this other extension, it can be found here:
http://pecl.php.net/package/uploadprogress
Hi, also
$status = apc_fetch(’upload_’.$_POST[’APC_UPLOAD_PROGRESS’]);
oder
$status = apc_fetch(’upload_’.$_GET[’progress_key’]);
gibt immer false zurück, kann mir einer sagen warum?
hi guys im a total novice at php, im trying to create a php file uploader, ive done it, but comes up with this message
Warning: move_uploaded_file(upload/1.jpg) [function.move-uploaded-file]: failed to open stream: Permission denied in /home/bizcli00/public_html/upload.php on line 5
Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move ‘/tmp/phpvIT1nr’ to ‘upload/1.jpg’ in /home/bizcli00/public_html/upload.php on line 5
Sorry, there was a problem uploading your file.
what am i doing wrong? its driving me mad
would appreciate any help
regards
Chris2
I use a Debian server with php 5.2.1 (from dotdeb). Apc is also from dotdeb.
I have used the source (but with some extra php like move_uploaded file).
This all works but I dont see the bar moving.
It goes from 0% to 100% when its done and is see this msg:
undefined bytes uploaded!
Upload rate was NaN kbps.
Has anyone encountered a similair problem? Could it be an APC issue?
[…] You can see some examples and code here: http://www.whenpenguinsattack.com/2006/12/12/how-to-create-a-php-upload-progress-meter/ (for APC) http://blog.joshuaeichorn.com/archives/2005/05/01/ajax-file-upload-progress/ (for UploadProgress, good php code but not HTML code, please check the comments to see how write your HTML). And restart your apache server; the fact is that under dotdeb and debian etch I wasn’t able to get work this, I even modify a bit the code of uploadprogress to write a file when the module was inited and when was called for updating the progress of the upload. The init was ok, but updating was never done. […]
If you get:
undefined bytes uploaded!
Upload rate was NaN kbps.
It could be one of two things.
Either you have forgot to enter the following line in php.ini
apc.rfc1867 = on
OR you may have also got another library loaded, which was my problem. I had both of the following extensions defined in my php.ini, 1 of them being required for this example:
extension=php_apc.dll
extension=php_uploadprogress.dll
The second line (php_uploadprogress.dll) above will cause this example to return the ‘undefined bytes’ error. I removed that extension from my php.ini and it all works now. Well to the point that it uploads something somewhere…the somewhere being thing I will tackle next
Thanks for the tip james!
Hmm.
There seems to be a problem with php_apc for php 5.2.1 on a windows IIS server.
The problem occurred on my production server, loading the dll as normal using the extension=php_mysql.dll define will cause PHP to crash with an “access violation error”. It has been reported by other users as a problem :sigh: (back to the drawing board)
I have not found a fix for this, perhaps downgrade to php 5.1.6 and use the compile of the apc specific for that version.
Just for closure on the problems I have had above, downgrade to 5.1.6 does not fix the issue.
Shame on my test system this works perfectly and I have integrated it with an upload class…this was a great platform to leap forward from. Thanks to Justin for his insight and work he put into this solution.
Im now having to look into some other way of doing a progress bar. Any thoughts on other methods greatly appreciated.
You could try an ajax based solution. Here is a good example (it’s near the bottom of the page)
http://www.dhtmlgoodies.com/index.html?page=smallscripts
hi can you help me the code for creating directiry using php
There is a command called mkdir that will do this. Here is some more information on how to use it: mkdir information
Please help.
Followed all instructions, but the upload bar dont get updated. It goes from 0% directly to 100% after upload completes. It gives me the message with the correct bytes uploaded at the end, but the upload rate is not correct, it shows the rate as if the upload was done in 1sec, when it really took much more.
Where should I start debugging?
Please help!
Some more info, using Fiddler debugging proxy I got this info:
This part of the code:
$status = apc_fetch(’upload_’.$_GET[’progress_key’]);
echo json_encode($status);
exit;
Returns this every connection made:
5
false
0
But this part of the code:
$status = apc_fetch(’upload_’.$_POST[’APC_UPLOAD_PROGRESS’]);
$status[’done’]=1;
echo json_encode($status);
exit;
Returns This:
d1
{”total”:249903,”current”:249903,”rate”:1999224,”filename”:”C:\\Documents and Settings\\Bruno G\\Desktop\\LogomarcaCMYK.jpg”,”name”:”test_file”,”temp_filename”:”\/tmp\/phpSdLJGI”,”cancel_upload”:0,”done”:1}
0
Seems like apc_fetch is not finding the cached variable on the new connections made to check progress, but is finding the cached variable for the connection made by the form submit. I’m very lost… Dont know where to start debugging.
Thanks a lot!
APC will not work with PHPsuEXEC. After recompiling apache without PHPsuEXEC APC started caching correctly.
But I still have problems, variable is only cached after upload is done. I can see it getting cached using apc.php only after file upload is complete. Still trying to figure out the problem.
After doing some research, I have found some better upload progress bars than the one in this article.
You guys may want to try these instead:
http://sourceforge.net/projects/uber-uploader - uses ajax
http://php5.bluga.net/UploadProgressMeter/demo.php - uses a hidden frame
Got it working.
APC upload will not work correctly with phpsuexec and mod_security.
Javis Hildebrand wrote on January 4th, 2007 1:13 am:
>ok so i figured out where to put the move_uploaded_file.
Where did you put the code?
hi, is it possible to do this feature by not using php.?
like html or asp ?
Eddy,
Did you get yours working? I’m having the same problem. Please email me at luke[at]lukem[dot]co[dot]uk
I’m getting exactly the same problem using Ubuntu (based on debian) and 5.2.1 so I’m guessing it could be environmental.
thanks!
Hello. Sweet articles!
Im on windows, and also got these access internal error, shutting down..
Make sure you dont have multiple cache services!
I turned zendoptimizer off and voila. (Didnt even know i had it on so it took a while to figure out the error).
Works like a charm!
>>ok so i figured out where to put the move_uploaded_file.
>Where did you put the code?
This works for me:
if($_SERVER[’REQUEST_METHOD’]==’POST’) {
$status = apc_fetch(’upload_’.$_POST[’APC_UPLOAD_PROGRESS’]);
$status[’done’]=1;
/* Upload finished! */
$uploaddir = “/home/katschro/files-upload/”;
$uploadfile = $uploaddir . $_FILES[’test_file’][’name’];
move_uploaded_file($_FILES[’test_file’][’tmp_name’], $uploadfile);
chmod($uploadfile, 0660);
echo json_encode($status); // Back into madness
exit;
…
It was difficult to debug. So if you have an error into this part, the uploadbar don’t work at all.
Is there any suggestion on how to bypass the single-thread issue?
It seems that (at this point, as mentioned in the related manual page) you have to wait for an upload to finish before initiating another one.
So, any ides or suggestions? is there a multi-thread version coming up?
Thanks
Just as a reiteration of Bruno G’s posts, if you are using phpsuexec and/or have mod_security enabled, APC will fail to report valid data. If you have mod_security enabled in your Apache configuration, data will not be written to the cache in real time, but rather will only be updated once the upload has finished. For reference, I’m running Fedora Core 7 with apache 2.2.0, PHP 5.2.2, APC 3.0.14. Hope this helps.
Has anyone tried seeing if the IIS issue got fixed in PHP 5.2.3?
The 5.2.3 changelog mentions something about HTTP_RAW_POST_DATA getting fixed, but did anyone determine if this was the problem? I’m actually writing an app on an IIS box RIGHT NOW and would love to get the upload progress bar working without needing to use a perl script.
Hey guys, finally I set up the working progress bar using php and apc. Check this out and send me an email with your comments. I am gonna improve it with multiple uploads.
http://iisphp.com/upload_progress_meter/
I was wondering if the phpupload progress bar here:
http://php5.bluga.net/UploadProgressMeter/demo.php - uses a hidden frame
uses ajax?
I cannot install anything having to do with asp files on my server because of xampp and this upload file looks really nice…
BTW, with the topic php upload progress bar, there was a question about where to put the code to permanently keep the files… but it was never answered.
I understand this is the code to keep the files
$uploaddir = ‘’; //put your permanent directory path here
$uploadfile = $uploaddir . basename($_FILES[’upload_form’][’name’]);// you might have to add a name=upload_form tag to the form in the demo
//make sure the directory you are copying this file to has proper write permissions
move_uploaded_file($_FILES[’userfile’][’tmp_name’],$uploadfile);
but where does it go?
Hey, just a note for some people who are asking questions about PHP upload file handling in general. This is a topic WELL documented on the PHP website, and questions about handling PHP uploads can be asked in the Google Groups forum for PHP and other places.
Here’s a link to the PHP documentation handling PHP file uploads:
http://us.php.net/features.file-upload
Get a regular Post upload working in PHP and THEN try and implement this project. You’ll have a much better background to be able to get it working. This is NOT a plug and play solution. Don’t worry, within another six months there will be much better implementations of this.
“uses a hidden frame
uses ajax?
I cannot install anything having to do with asp files on my server because of xampp and this upload file looks really nice… ”
It looks like it uses a hidden frame + a php extension.
Hi Justin, great article.
I noticed the progress percentage indicatior slides off of the right side of the viewable area, seems to be a div after the progress bar animation div and gets pushed over as the progress bar gets fuller. How can I fix this?
Cheers,
gordon
[…] You heard right! Just add an apc.rfc1867 = on to your PHP ini and submit also a APC_UPLOAD_PROGRESS>-field and your on the right side calling the progress like with apc_fetch(’upload_’.$_POST[’APC_UPLOAD_PROGRESS’]); For more just have a look here and enjoy […]
I have a file uploader that I wrote and I am having a little trouble implementing this. The upload works just fine when I use a regular form to submit to it, but for some reason when I use the upload progress meter, the bar stops when the file is complete and never finishes. FOr example, the bar will go from 20% to 50% then 90% and stop. I have thoroughly tested the upload code I am using, so my guess is that the ajax request is timing out before the script finishes executing. Here is my code:
if(isset($_POST[’APC_UPLOAD_PROGRESS’])) {
$status = apc_fetch(’upload_’.$_POST[’APC_UPLOAD_PROGRESS’]);
$status[’done’]=1;
if(empty($_POST[’dir’]) || $_POST[’dir’]==’0′ || !folderExists($_POST[’dir’],$_SESSION[’uid’])){
$folder = $settings[’main_folder_path’].’/’.$_SESSION[’uid’].’/';
} else {
$folder = $settings[’main_folder_path’].’/’.$_SESSION[’uid’].’/’.folderPath($_POST[’dir’],$_SESSION[’uid’]).’/';
}
$filename = basename($_FILES[’test_file’][’name’]);
$target_path = $folder . basename($_FILES[’test_file’][’name’]);
if(move_uploaded_file($_FILES[’test_file’][’tmp_name’], $target_path)) {
$mime_type = MIME_Type::autoDetect($target_path);
$filesize = filesize($target_path);
dbAddFile($filename,$_POST[’dir’],$mime_type,$_SESSION[’uid’],$filesize);
}
echo json_encode($status);
exit;
} else if(isset($_GET[’progress_key’])) {
$status = apc_fetch(’upload_’.$_GET[’progress_key’]);
echo json_encode($status);
exit;
}
Anyone have any ideas? Thanks.
Original by James:
“If you get:
undefined bytes uploaded!
Upload rate was NaN kbps.
It could be one of two things.”
No, there could be a third reason.
Try it with really small files, if you get this error.
If this works you have to increase your ‘upload_max_filesize’ and ‘post_max_size’ in the php.ini
Hi Justin,I just use your script in my computer,But it always meets this problem below:
missing } in XML expression
{”done”:1}
my php version is 5.2.3,what’s the problem about it.thank you for your great work.
Hello Justin,
I use this script in my pc.
all thing is ok but the script dont save any uploded files!
what can i do?
Hi Folks,
I grabbed the demo progress.phps on my debian machine.
installed apc, and configrued as mentioned.
The file uploads fine.
Problem is: I don’t see the progress bar moving!
I can drag the box around, but no progress bar.
Any ideas?
Help!
Thanks!
Hi
Very interesting information! Thanks!
Bye
im having a big problem!
http://www.divingtube.com/phpinfo.php says that apc is installed and apc.rfc1867=on. however it still doesnt work! ive reset apache too to no help…
the file gets uploaded ok but the progress bar stays at 0% and then suddenly goes to 100%.
please help because ive been trying this for hours now!
cheers
doesn’t look like a “live” upload progress bar to me. the progress bar does not move during upload!
apc progress bar does not seem to work in a load balanced environment. it only works with one server, can someone confirm that?
Thanks. Good article
is it possible to upload multiple files using this APC technique?