PHP 5.2 upload progress meter

Yesterday I’ve spent considerable amount of time in order to find out more about the most interesting new PHP 5.2 feature – hook for upload progress meter. Except for this link I haven’t found anything else, no php source code example how to make one.

However, after I looked at internal php mailing list archive, I’ve found this thread, still no php data found, but Rasmus mentioned link with an example at http://progphp.com/progress.php. I immediately tried upload and it looked very cool. Then I looked at html source code and noticed one unusual thing there: APC_UPLOAD_PROGRESS hidden field inside of html source. I knew it must be important so I’ve googled for it, and insteresting enough first result was source code of Rasmus example above :)

So, I took complete source (I figured out later it is upload meter example made by Rasmus Lerdorf) and quickly tried to make it working under my fresh new installed PHP 5.2.0. Unfortunately, it didn’t work since it needed apc stuff installed. After I looked at apc documentation, I found that I need to grab it from list of pecl dll’s for windows php 5.2 version. Unfortunately, after I’ve downloaded it from here I’ve noticed apc dll is missing there ?!!

Again, I had to google for php_apc.dll and after a while found needed dll available at http://pecl4win.php.net/ext.php/php_apc.dll. In order to make it working, you have to save dll file under php/ext dir (i.e. c:\php\ext on windows) and put this to php.ini:

extension=php_apc.dll

Unfortunately, it still didn’t work, so I’ve looked at apc docs further. Finally on this page I’ve found apc have new “special feature” which is directly related to our new upload feature.

    apc.rfc1867             RFC1867 File Upload Progress hook handler 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.
                            (Default: 0)

After I figured out on my phpinfo page apc.rfc1867 setting is turned off, I’ve added

apc.rfc1867 = on 

in php.ini, and after restart was finally able to enjoy new fancy upload progress meter :)

upload progress meter

Btw, upload also depend of json turned on as well, but it was already turned on so I didn’t have any more problems.

About the code Rasmus used in his example, I am tired to analyze it more now, but obviously it use Yahoo! User Interface Library to create progress bar and json/apc to control it from php during file upload.

I hope this will be helpful for someone. Enjoy ;)

Comments

  1. November 5th, 2006 | 8:26 pm

    [...] (more…)   [...]

  2. Tore Krudtaa
    November 8th, 2006 | 10:37 am

    Thanks for the

    apc.rfc1867 = on

    hint, that made it allmost work flawlessly.

    Found an annoying bug though.

    If you make a multi file upload_form and do not fill out all of the file fields then the
    cancel_upload parameter get a value of 4 and the the whole upload is reported as:

    Cancelled after 109300234 bytes

    even if the upload actually was a success.

    If anyone comes up with a workaround or fix for that would be great.

    Except for that I would like to see a solution where we did not have to use APC to make it work.

  3. Tore Krudtaa
    November 8th, 2006 | 10:35 pm

    Upload progress meter not working in IE (6.0) either.

    Tested against:
    http://progphp.com/progress.php

    I suspect that is more to do with YUI and/or JSON ..
    will make a custom AJAX like replacement for those and see what happens tomorrow.

    Anyone else with info on this?

  4. November 9th, 2006 | 10:50 am

    Yeah, I noticed after your comment that progress meter doesn’t work in IE6, but didn’t have a time to look at it. When i get a chance will do and let you know what I’ve found :)

  5. Tore Krudtaa
    November 9th, 2006 | 1:50 pm

    Filed a feature request to php bugs database asking that they make this new upload variables in 5.2 using session variables instead of APC objects.

    http://bugs.php.net/39447

    Do not see why we should have to use APC to get this thing working in PHP.

    It could be an optional feature though, controlled by a php.ini variable.

    Hope they can do this ASAP.

  6. Tore Krudtaa
    November 12th, 2006 | 10:38 am

    The reason it did not work in IE was because of caching issues.

    In IE it fetches the first get request from server and then the rest from the cache.

    To avoid it we can use:

    } else if(isset($_GET['progress_key'])) {
    header( “Expires: Mon, 26 Jul 1997 05:00:00 GMT” ); // disable IE caching
    header( “Last-Modified: ” . gmdate( “D, d M Y H:i:s” ) . ” GMT” );
    header( “Cache-Control: no-cache, must-revalidate” );
    header( “Pragma: no-cache” );

    $status = apc_fetch(‘upload_’.$_GET['progress_key']);
    echo json_encode($status);
    exit;
    }

    Or eventually put a counter in the URL used to produce a get request in order to make each get request unique and thereby preventing IE from caching.

    Note that there seem to be a bug if you have more than one file fields in the the upload form, and only uses some of the fields (and the empty fields are not disabled before submitting the form)…
    then the cancel_upload parameter will be set to 4 even if the upload went okay.

    Using a javascript to check if some of the fields are empty and disabling those fields before submitting the form will (in most cases) prevent cancel_upload to get the value of 4.

    Regards

  7. November 17th, 2006 | 7:06 pm

    [...] 這篇文章也介紹了用 PHP 5.2 加上 Yahoo! UI Library 來作一個 AJAX 的 upload progress bar。 [...]

  8. Sean
    November 20th, 2006 | 10:46 am

    How do you make this work with linux?

  9. November 22nd, 2006 | 11:58 am

    I keep getting back response false :(
    Any ideas?

  10. November 22nd, 2006 | 12:52 pm

    Hi !

    On my Wamp Server, there is no problem to make appear the progress bar (i’ve rewrite the code in a Prototype.js way , i prefer !)

    But on my Lamp server, all i have it’s a “false” response from the apc_fetch(‘upload_’.$_GET["progress_key"])

    I’ve a problem with IE also despite the remarks of Tore Krudtaa about preveting cache…

    Enjoy the codes below :

    uploads.js

    function arrondi(m){return (Math.round(m*100))/100}
    function mega(m){return arrondi(parseFloat(m/(1024*1024)))}
    function uploadTermine(r){
    	if (r['cancel_upload']) txt = "Transfert annulé !";
    	else txt = mega(r['total'])+" Mo transférés !";
    	$('pbar').style.width = "100%";
    	if (txt) txt = " ("+txt+")";
    	$('ppct').update("100%"+txt);
    }
    function progressStatus(o){
    	var r = eval('('+o.responseText+')');
    	if(!r['done']){
    		if(r['total']){
    			var pct = arrondi(parseFloat(100*(r['current']/r['total'])));
    			$('pbar').style.width = pct+'%';
    			txt = pct+"% ("+mega(r['current'])+"/"+mega(r['total'])+" Mo)";
    		}
    	}else if (r['cancel_upload']) txt = "Transfert annulé !";
    	else if (r['current']==r['total']) uploadTermine(r);
    	$('ppct').update(txt);
    }
    function updateProgress(){
    	new Ajax.Request('ajax/upload_progress.php',
    		{parameters:'progress_key='+$F('progress_key'),onComplete:progressStatus}
    	);
    }
    function progress(){
    	new Draggable('progress',{revert:true});
    	new PeriodicalExecuter(updateProgress,1); 	$('pbar').style.width = "0%";
    	$('ppct').update("0%");
    	Effect.Appear('progress',2);
    }
    

    style.css

    body,input{
    	font:.85em 'Trebuchet MS';
    }
    #progress{
    	height: .85em;
    	width: 300px;
    	border:1px solid #000;
    	margin:3px 0 3px 0;
    	cursor:move;
    }
    #progress #pbar{
    	background: #FFC300;
    	height: .90em;
    	width:0%;
    	float:left;
    }
    #progress #ppct {
    	font:.80em 'Trebuchet MS';
    	margin: -2px auto 0 auto;
    	text-align:center;
    }
    

    upload.php

    <html>
    <head>
    <script type="text/javascript" src="js/prototype.js"></script>
    <script type="text/javascript" src="js/scriptaculous.js?load=effects,dragdrop"></script>
    <script type="text/javascript" src="js/uploads.js?p=1164196800"></script>
    <link rel="stylesheet" type="text/css" href="css/style.css" />
    </head>
    <body>
    <form enctype="multipart/form-data" id="formulaire" action="recu.php" method="POST">
    	<input type="hidden" name="APC_UPLOAD_PROGRESS" id="progress_key" value="45643bc03f565"/>
    <input type="file" id="test_file3" name="test_file3"/>
    <div id="progress" style="display:none"><div id="pbar"></div><div id="ppct">0%</div></div>
    
    <script type="text/javascript">Event.observe("formulaire","submit",progress);</script>
    	<input type="submit" value="Upload!"/>
    </form>
    </body>
    </html>

    upload_progress.php

    <?php
    if(isset($_POST['progress_key'])) {
    	echo json_encode(apc_fetch('upload_'.$_POST['progress_key']));
    	exit;
    }
    >
    
  11. November 22nd, 2006 | 12:59 pm

    sorry for the comment but i thought that the [code][/code] would work :

    Here’s the package http://www.agglo-larochelle.fr/uploads.zip

  12. November 22nd, 2006 | 1:00 pm

    If anyone has any idear about my lamp problem (json + apc activated, same config as wamp…)

    and the IE problem too…

  13. November 23rd, 2006 | 5:04 am

    Hey le_zell.

    I had the same problem as you, but have now fixed it. After hours of searching, I think the problem is that APC-3.0.12p2 doesn’t have rfc support built into it. I did some googling and found their CVS and downloaded the files for version 3.0.13-dev. I have made a tarball of these for you. Try installing this one and see if it works.

    http://www.nfsg.net/APC-3.0.13-dev.tar.gz

  14. November 23rd, 2006 | 11:08 am

    OOps,

    i must have a problem on my compilled librairy APC…

    a phpinfo() gives me : Fatal error: Call to undefined function apc_cache_info() in /home/intranet/www/phpinfo.php on line 5

    A future release of PAC will have the rfc support no ?
    We have just to wait these support ?

    thanks mike !

  15. November 23rd, 2006 | 11:16 am

    It’s explain a lot of things.

    I’ve tried to compiled a new apc.so extension but no sucess, a phpinfo() gives me fatal error on apc functions.

    So i will wait for the future support of RFC in the APC developpements.

    thanks mike !

  16. December 17th, 2006 | 10:54 am

    I’ve installed PHP 5.2.0 as FastCGI server API, but APC return false on every AJAX requests, Is it only working when php compiled as Apache module?

  17. December 18th, 2006 | 9:04 am

    I haven’t seen this posted anywhere but it has been giving me fits. Tests with multiple simultaneous file uploads through multiple iframe pipes or even in multiple browsers results in apc neglecting the first-created upload variable. So tracking one file at a time works fine but if I attempt to track a second file’s progress at the same time I can see by watching apc_cache_info(‘user’) that updates to the first upload_x variable stop occurring after the second file begins to upload.

  18. funk
    December 26th, 2006 | 2:40 am

    Hi, i dont have a clue about apache, or anything, maybe i can get into php.ini. i have a linux server, i would like to install that uploader but i get errors

    Warning: uniqid() expects at least 1 parameter, 0 given in /home/funk999/public_html/ajax/demo.php on line 3
    0%

    then once complete
    Array ( [test_file3] => Array ( [name] => http://www.wmv [type] => video/x-ms-wmv [tmp_name] => /tmp/phplv7owV [error] => 0 [size] => 369565 ) ) Array ( [APC_UPLOAD_PROGRESS] => )

    so.. i cant find where it has uploaded to… please help

    abdulwahid999@hotmail.com

  19. December 26th, 2006 | 10:13 am

    the script is only an example, if you want to store the files permanently look into the function move_uploaded_file… at the moment the file only lives in your temp directory and php deletes it after the page is generated.

  20. January 3rd, 2007 | 2:20 pm

    Thanks man! :) You did the hard work for us.. otherwise i would have had to follow the same path u took :) of searching ans trying.. thanks a lot! :)

  21. Bolle
    January 4th, 2007 | 1:05 am

    How to save the file permanently? For sure have i to use the move_uploaded_file function – but where since the action of the form is never being called.
    So please give me an hint how to call a PHP script with $_FILES available after the successful upload.

    Anyway a great Tutorial which saved me lots of time. Many Thanks.

  22. chein
    January 4th, 2007 | 9:05 am

    hello~

    i use version 3.0.13-dev,but rfc is not in my phpinfo,could anyone tell me something wrong??

  23. January 5th, 2007 | 10:08 pm

    Ok I have the progress bar working for single files but I would like to upload multiple files. How do I modify it to do this?

  24. sumer
    January 28th, 2007 | 2:23 pm

    OKAY SO.. let’s see.. The CGI uploaders can show kb per second and estimated time left, etc.. and move very fast..

    why should one use this PHP uploader?

    whats the point if it is not better than existing technology that is 10 years old?

  25. January 30th, 2007 | 11:14 pm

    Good reference. Thanks.

    Just a note for Linux users, you will need to download from current CVS and build it yourself. The current pecl module (3.12p2) doesn’t have the apc.rfc1867 property enabled.

  26. Polorboy
    February 5th, 2007 | 11:42 pm

    Ok, I got APC installed. i just stumbled across this script the same way you did, i did a search in google and just found the progphp.com/progress.php and tried uploading a file and it was exactly what I am looking for. I have a php script that can handle multiple files at one time, but how can I get this to work with that. There doesn’t seem to be any reference to a seperate php code that handles the file. What is it doing with the file? Also, when I try and run a page with the script exactly (copied and pasted pretty much, changed a few things and downloaded all the js files to my own server) all i get is a: {“done”:1} after it has uploaded the file. It doesn’t show the progress bar. I hope someone can help me out with this, this seems to be the answer to my problems.

  27. Nicolas
    February 14th, 2007 | 6:43 am

    I am also having problems tracking simultaneous uploads. Has anybody found a solution?

  28. February 16th, 2007 | 3:58 pm

    Hi i`ve tried to make this thing working on my local server and i have a problem with saving files.
    What should i write and where to make files save, and how can I check some file parameters 9like size or type) and get form back to user if it is with mistakes.

    I’ve writen in progress.php something like that
    if($_SERVER['REQUEST_METHOD']==’POST’) {
    $status = apc_fetch(‘upload_’.$_POST['APC_UPLOAD_PROGRESS']);
    $status['done']=1;
    echo json_encode($status);

    $file=$_FILES['test_file'];
    $name = $file['name'];
    $tmp_name = $file['tmp_name'];

    $filename=”$root_path/mp3/$name”;

    move_uploaded_file($tmp_name, $filename);

    But it makes progress bar not to display progress but file gets loaded into dir.

  29. harald
    February 23rd, 2007 | 9:08 am

    hello!
    i added the
    apc.rfc1867 = on
    to my php.ini.
    but after restart it´s not shown in the phpinfo() ?
    i can see the apc – part, but not this rfc1867 stuff…
    what´s my problem? :(

    thank you!

  30. Emil Ivanov
    March 8th, 2007 | 9:33 am

    Regarding the IE issue – use POST requests. For some unknown reason IE caches GET requests, even when you tell it not to do and expire the cache. I’m not sure, but I think they fixed it in IE7.

  31. Tom
    March 14th, 2007 | 9:12 pm

    apc.rfc1867 = on

    Thanks… I was ready to start screaming.

    That really helped. Will try to post an example using this with dojo.io in a few days here. I have all of the dojo part working which barely has any docs, and the php barely has any docs either, but this was the key for the php part.

  32. Ath
    April 2nd, 2007 | 4:57 pm

    Hi,

    I am working on an HTTPS file uploader using APC. I have a linux/apache server. It works very well on Firefox, but not on IE. Have you a solution for this problem.

    I disabled the IE cache (using the header lines), but it does not change any thing.

    Thanks.

  33. Gerard Pastis
    April 16th, 2007 | 10:20 am

    Working On IE 6 & 7:

    function update_progress() {
    var currentTime = new Date();
    progress_key = document.getElementById(‘progress_key’).value;
    YAHOO.util.Connect.asyncRequest(‘GET’,'progress.php?progress_key=’+progress_key+’&time=’+currentTime.getTime(), progress_callback);
    }

    but be sure that you don’t post files that apache configuration don’t accept.

  34. Luke Mackenzie
    April 19th, 2007 | 1:04 pm

    le zell – what about recu.php? you dont include that and the link to your zip file no longer works. please repost!

    thanks,

    luke.

  35. tata
    April 23rd, 2007 | 9:12 am

    how this work in php 4.2 or tried version

  36. April 25th, 2007 | 2:44 am

    The upload tracking feature in this extension DOES NOT work on multi-threaded web servers… If you are having trouble trying to track multiple simultaneous uploads this may be the problem… http://pecl.php.net/bugs/bug.php?id=9645&edit=2

  37. June 20th, 2007 | 2:42 am

    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.
    It also displays the estimated and elapsed time too.

    http://iisphp.com/upload_progress_meter/

  38. November 21st, 2007 | 12:52 am

    Hey, I just wanted to try this upload meter, too, and ran into another problem. apc_fetch() returns false to me most of the time. At the very first upload I tried, it sometimes returned some data, but now it doesn’t anymore. I have a FastCGI setup with PHP 5.2.4 and APC. The problem is this: FastCGI runs multiple PHP processes that handle requests. Every HTTP request runs in under a different PHP process. I could test this with getmypid(), which is different every time, but only from a limited set. apc_cache_info() shows all upload_* entries for a process, but only for this specific process. So if I upload a file to one process, I can only get progress info from the same process again. But since every HTTP request comes to a different process, this works in only a few cases and often just returns false. It seems that every PHP process in FastCGI has its own APC cache, so this feature is nice but useless in these environments.

  39. Axel D
    December 5th, 2007 | 2:42 pm

    Hi, we have a IE6 & 7, and Mozilla Firefox, with IE any version all working fine, but with Firefox, the window upload animation don’t progress. any body have a idea.

  40. December 5th, 2007 | 8:01 pm

    Hi, I’ve tryed this piece of code on two server and on an ubuntu with PHP Version 5.2.3-1ubuntu6 it works fine.
    On OpenSuse with PHP Version 5.2.4 I’ve the problem that apc_fetch returns always false.

    I’ve compared the phpinfo() for the two servers and in apc section are equal.

    I’ve tried the suggestion of Yves, and looked at pid with the function getmypid().
    The pid are always equal, but the returns of apc_fetch it’s always false.

    Anyone can suggest me what type of debug I can do?

  41. RogerShih
    December 14th, 2007 | 4:53 am

    to Tore Krudtaa:

    in IE, ajax can set send uri a different, let IE work. like add a rnd=Math.random()+new Date().getTime().

    In jQuery, it’s needn’t to do this.

  42. December 18th, 2007 | 10:36 am

    Well now if only apc would work with ioncube :(

    Anyone know if it does or not ?

  43. smartcoder
    January 10th, 2008 | 8:57 am

    Download Project Management System developed in PHP,MySQL from http://phpfunda.blogspot.com/2007/09/project-management-system-in-php-mysql.html

  44. March 25th, 2008 | 3:37 am

    hi,
    great…!
    i’m working on this.
    very thanks…

  45. Alex
    April 11th, 2008 | 5:29 pm

    I’ve read this discussion but I still can not find how do I save the uploaded file ?
    Let’s say I already had a form in *.php file which contains some fields and the file to upload. Now I want to add the feature to track the file upload progress to the existing form using this example and yui Java scripts.
    Should I include this form in iframe as a part of progress.php ? What is the best approach for this ?
    Thank you to everyone in advance,
    Alex.

  46. Jake
    April 17th, 2008 | 10:39 am

    Has anyone experienced results from apc_fetch such as the current number of bytes transfered being greater than the total number of bytes transfered? I experienced this on Windows 2003, PHP 5.2.5 with Apache 2. The problem isn’t consistent but does happen randomly. Usually when multiple uploads by different people are taking place.

  47. erik
    May 30th, 2008 | 11:32 am

    I have similar problem as Paul had. The one that tests with multiple simultaneous file uploads through multiple iframe pipes or even in multiple browsers results in apc neglecting the first-created upload variable.

    Can someone help me? Please.

  48. Tore Krudtaa
    September 13th, 2008 | 12:29 pm

    Hi there.

    Finally the upload hooks will be available using session variable.

    This is now submitted to head for the PHP 6.
    The guy working on it says he will try submit to 5.3 as well in not to long time.

    So, in a short while (hopefully) we can start using the upload hooks without the need for APC, PECL or whatever….

    Just a plain php installation…

  49. March 12th, 2009 | 2:05 am

    [...] Der Sourcecode dazu: http://progphp.com/progress.phps Die Links stammem aus: http://www.dinke.net/blog/2006/11/04…ress-meter/en/ Vieleicht reicht Dir das bereits an Infos. MfG, [...]

  50. Yogesh
    March 23rd, 2009 | 7:45 am

    Hi All,

    I am using wamp server on my local:
    I followed steps as below:
    1.C:\wamp\bin\php\php5.2.8\ext\php_apc.dll

    In php.ini file
    1.extension=php_apc.dll
    2.apc.rfc1867 = on

    and I restarted wamp server
    I tried to upload file
    but unfortunately I am getting error
    Fatal error: Call to undefined function apc_fetch() in C:\wamp\www\UploadProgress\uploadProgress.php on line 3

    Please help it’s urgent.

    Thanks & Regards

    Yogesh

  51. Tom
    March 25th, 2009 | 11:44 am

    Hi Yogesh,

    have you set
    apc.enabled = 1
    in your php.ini? All settings are explained at
    http://de.php.net/manual/en/apc.configuration.php

    Also, in the APC package available at
    http://pecl.php.net/package/APC
    you can find a script called “apc.php”. Call it in your browser and you can monitor the status of your APC cache.

    Cheers
    Tom

  52. March 25th, 2009 | 12:15 pm

    @Yogesh
    It looks that you don’t have apc installed.

    Old link in my article doesn’t work anymore but you can downlod it from link Tom provided.

  53. July 9th, 2009 | 10:25 am

    Doesn’t work, tried uploading a 500 MB file and it said completed within 3 seconds. I know my upstream isn’t more than 48KB/s, so there is no way it actually uploaded.

    I am also not going to digg this, because its really no brainer, Upload with progress bar has been around for quite some time, which all they did was refresh the popup window. Now it just a AJAX version of the same.

    Firefox 1.5.0.1.

  54. August 26th, 2009 | 3:04 am

    [...] Caught in a Web » PHP 5.2 upload progress meter http://www.dinke.net/blog/2006/11/04/php-52-upload-progress-meter/en – view page – cached Yesterday I’ve spent considerable amount of time in order to find out more about the most interesting new PHP 5.2 feature – hook for upload progress meter. Except for this link I haven’t found anything else, no php source code example how to make one. — From the page [...]

  55. alex
    September 9th, 2009 | 12:58 am

    I have been trying to get this to work, and have exactly the same issue as a few people on here. It works great in IE, but not Firefox3…

    I get the progress meter comeup and then it shows me {blah:1 blah:1} – but the file is uploading. It just doesn’t seem to refresh the parent as it doe sin IE.

    Any ideas would be appreciated..

Leave a reply