There and Back Again

PHP AJAX File Upload Progress Meter Updates

Over the weekend my file upload progress meter code got lots of traffic. It seems it made it made it on the del.icio.us popular list as well as getting over a thousands diggs. To celebrate this i’ve updated the code.

The main new feature is giving you feedback without having to patch PHP. Now the patched version gives you more information such as upload speed and estimated time to completion. But we still provide some nice user feedback even without it now.

I also created some wiki pages to start the documentation process.

So here are the demo’s

With the patch and extension
Without the patch

To get upload speed you will need to download and install the PHP Upload Progress Patch and extension.

If you want to use the code you need to:
Install HTML_AJAX (pear install HTML_AJAX-alpha)
Download PAFUPMU and install it somewhere accessible.
Add the code to your page using demo.php as an example.

The basic way the code works is we take a form containing a file upload and submit it using a hidden iframe as a target. Doing this lets the upload happen in the background. Then we poll the server on a regular basis (say a 2 second interval) asking it for update status. If you have the patch+extension installed this gives you file upload speed etc. If you don’t have the extesion we stop making AJAX calls and just animate the status bar until the upload finishes in the iframe and tells us were done.

In demo.php we handle generating the current page and handling the upload in the same page. So we start by handling the update.

<?php

include 'UploadProgressMeter.class.php';

$fileWidget = new UploadProgressMeter();

if ($fileWidget->uploadComplete()) {
        // output javascript to the iframe to send a final status to the main window
        // this will catch error conditions
        echo $fileWidget->finalStatus();

        // move the file(s) where they need to go

        exit;
}
?>

?>

This code only runs when your uploading so you’ll never see the output of it. This can make debugging problematic. One way around this is too hack the UploadProgressMeter to make the iframe non hidden.

Next you setup the JavaScript needed, first HTML_AJAX and then the uploaders JS.

demoserver.php is included in the source, you might want to name it something else if you actually use this code. Its just a page using HTML_AJAX_Server to register the UploadProgressMeterStatus class

You also need some CSS to style the progress bar. The only important thing is that .progressBar and .progressBar .bar are relatively positioned.

Finally you finish things up by building a form. Note that you can include other elements in the form, but if they need to produce output you’ll have to manage calling back into the parent page from the iframes output.

131 thoughts on “PHP AJAX File Upload Progress Meter Updates

  1. Joshua Eichorn Post author

    lin: Your still performing a normal upload, its just happening inside a hidden iframe.

    So you handle the upload just like normal in PHP. There is a comment in the script with where to add the upload code, move_upload_file etc.

  2. matt

    hi josh!

    great script! but i have the same problems rumen had in comment 93.
    in opera and internet explorer 7 sometimes i got a timeout, sometimes it goes immediately to 100% and sometimes there is just a “connecting”.
    have you any ideas about that issues?

    everythings working fine in firefox and safari.

    a test script: http://www.sprtpc.de/app/includes/demo.php

    thanks for your help
    matt

  3. Kevin

    Hallo joshua,

    Lovely script, real good work!
    I am getting the error: ‘UploadProgressMeterStatus’ is undefined.
    U have any idea how to fix this?

    Thanks for your help,
    Kevin

  4. Dinesh

    Dear Joshua,

    I am unable to get the upload speed working. I am only getting the animated progress bar. Please help! I have HTML_AJAX, pear and the uploadprogress extension installed. I am running PHP 5.2.3. Is there a way to debug this myself? Any help or advice would be greatly appreciated. Thanks!

  5. Joshua Eichorn Post author

    Dinesh make sure you have the most recent update progress code from svn.
    Also for debugging i use the firebug firefox extension or the fiddler2 debugging proxy. Take a look at the ajax requests and see what is getting sent back.

    My best guess would be taht the uploadprogress extension isn’t getting detected correctly

  6. Dinesh

    Wow! That simple eh? I had forgotten to load the extension in the php.ini file. I added the line extension=uploadprogress.so and restarted apache and Viola! It works now. Thank you very much for the tips/advice. This might sound like a stupid question, but is there a way to manipulate the way the uploaded bytes and uploaded percent looks on the browser/client? In other words, can I change the font and format? By the way, thank you for the excellent scripts and the time you put in to writing them and supporting them.

  7. Dinesh

    Joshua,

    Thank you! On a side note, I have noticed that a lot of the time the bar jumps from connecting to upload complete without showing any file progress. Am I doing something wrong or is this a bug? I am using IE 6. What can I do to fix this?

  8. Dinesh

    When it jumps from connecting to upload complete, it seems almost instant. Maybe a few seconds. When I look in the upload folder I see a partial upload and the file name is not what it is supposed to be. The file name looks like phpvNR1bM instead of winscp407.exe. There are other times when it uploads the complete file with the correct file name.

  9. Dinesh

    Sorry, I forgot to mention that during those “other” times the upload is not instant. It does take a normal amount of time to upload the file, but I just dont see the file progress. It just jumps from connecting to upload complete.

  10. Dinesh

    Still having problems with the bar jumping from 0 to 100% although it does upload the file. I can see that the browsers built-in status bar is working. Is this a cache issue? What could be causing this behavior. If I delete cookies and I delete browsers cache/files and reload the page it works. I have added the followig in the head tag, but it does not seem to help:

  11. xbilgix

    where will File uploaded? i tried it but nothing uploaded file ???

  12. ian

    I found that after a download or two, my meter quit working. I think there is a race condition, where UploadProgressMeter could be decremented twice when a download finished, once in window.uploadComplete() and once in UploadProgressMeter_Update(). UploadProgressMeter_count would become negative, and subsequent upload attempts would have no meter. I changed both subtractions to the following. YMMV.

    if (UploadProgressMeter_count > 0) {
    UploadProgressMeter_count–;
    }

  13. Richard Miller

    For those finding the meter jumps from 0 t0 100% it may be the following issue which I had:

    The hidden form field named APC_UPLOAD_PROGRESS needs to go before the file input field otherwise it is not received by the server until the file has been uploaded. Obvious in hindsight I guess but kept me busy for a while.

  14. Avis

    I try to use this demo.php but it gives the error as dbug:
    Form Submision Iframe Target:
    array(1) { ["upload"]=> array(5) { ["name"]=> string(14) “groups_bar.gif” ["type"]=> string(9) “image/gif” ["tmp_name"]=> string(23) “C:\WINNT\Temp\php9E.tmp” ["error"]=> int(0) ["size"]=> int(2200) } }
    What is happning……..?????
    Why nothing is uploading……..????

  15. Jsalinas

    Hello Joshua, I am have a problem with the HTML_AJAX 0.5.5 package. I have installed HTML_AJAX through the PEAR package manager, and completely tested it as well. I checked the include_path in the php.ini– all ok. I also run the HTML_TEMPLATE package on it already without a problem.

    Yet, for some reason, when I used the example code from –“http://wiki.bluga.net/HTML_AJAX/start?#”, I get 2 errors on the javascript: “HTML_AJAX.replace is not defined” , and a syntax error on the “”, however I removed the DOCTYPE tag from all file. Yet, It’s still indicating a problem. I copied the files exactly from the example code, creating 3 file: the server.php, the page.html and output.php
    Basic Setup:
    Apache 2.0.53
    HTML_AJAX 0.5.5
    php5.2.5
    PEAR 1.7.2

    I would really “appreciate” any help you can give me.
    jsalinas

  16. Rob C

    Hello Joshua,

    I was just wondering if you’ve given consideration to providing a view of the image after it is 100% uploaded, or did the demo above not work properly, and it should have shown a small image of the file that has been uploaded?

  17. Joshua Eichorn Post author

    jsalinas:

    sounds like the the js code isn’t being delivered properly and is throwing errors. Try viewing the js includes manually.

    Rob c:
    That sounds like a pretty reasonable thing to do but the current demo leaves what to do with the files after upload up to you.

  18. Antonino

    Hi Joshua,

    great job, it has worked for me first run.

    Now the issue:
    I need to reload the main page when upload ends: how should I accomplish that?

    thank you

  19. Pingback: Need help with a PHP upload script - DesignersTalk

  20. Stephan

    The upload page loads fine but nothing get’s uploaded to the server the status bar says in progress I loaded the debug view and when I click upload a page cannot be displayed (404) is loaded into the iFrame. Also where can I tell the server to upload the file to. I have a folder under the main page where I would like the files uploaded to.

  21. Pingback: 120+ Javascript, Ajax, jQuery Mega Toolbox | tripwire magazine

  22. Pingback: Finally! File Upload Progress for php (5.2) - Dreaming of Dawn