Script Perfect

         Random snips of code and bugs

PHP File Upload Progress (APC Fetch PECL)

Posted by Tim On September - 4 - 2009

You would think that tracking file upload progress would be a given now, from your browser you can create websites, edit pictures and communicate with millions of people. Only a few sites will actually show you your upload progress and they are few and far between. If anything they will show you a nice animated gif that gives you the illusion your file is being transferred.

It is very possible to track upload progress but I have some bad news for some of you. If you are hosted on a shared server like Hostmonster, BlueHost, etc… then odds are you will not have the right privileges to install the required modules. For those of you that have access to your own server or the capability to get it installed then read on.


You can download the full source for this by clicking here. But I strongly recommend you read this!

Installing APC

First we need to install APC created by PECL. Unfortunately there is no longer support for this on windows based machines but you can still find the dll floating around the internet if you look hard enough. If you do get the dll and you want to use it with WAMP or any other type of local setup simply place it in your php folder with the rest of the dll’s under the “ext” folder. If you are installing remotely like on a server you can use the “wget” function to grab the files and the “gzip” command to extract. There are plenty of resources which can show you how to install, I will show you how to set it up and use it.

Windows Users: If the dll you find does not work try a different version, I had to try 3 different ones to get it to work on my local box.

Once you have the package or dll installed in your machine you will need to edit your php.ini file to configure some settings on apc. Search your php.ini file for “extensions” and you should be presented with a list of them, you need to add the following line:

//WINDOWS USERS:
extension=php_apc.dll
//CentOS or similar
extension = “apc.so”

This will activate the file in windows or on your server. Next you will need to instruct APC to monitor file uploads by adding the following line to the php.ini:

apc.rfc1867 = On

RFC 1867 is a document that describes how HTTP file uploads work for those of you that are curious. The final step in setting up APC is simply restarting your server.

Monitoring File Uploads With APC…The Code

So here is the thing, we actually need to use a combination of things to make this work correctly. First we need to set up our form and a unique key that can be used to track the file progress. We also need a few JavaScript / Ajax functions which will allow us to track the upload without refreshing the page. Finally we need a php function which will report the progress back to us so we can display it on the page. Below is an overview of how it will all work.
I will explain this step by step:

Step 1: We post our form with the file we are uploading, the data is collected by our JavaScript functions and we remain on the same page.

Step 2: The JavaScript will post all of the data to the php upload file and start our php progress indication.

Step 3: We use a JavaScript function to pull the upload progress from our php progress file, the progress is being tracked based on the file being uploaded in our php upload file.

Step 4: We update the files status in our progress area on the webpage.

Creating Our Form and  a Key to Track Progress:

At the top of the page where our form resides we will need to generate a random string of characters which will be used by the APC function to track the files progress. We will need to include that value in our form, your form should look like the following:

<?php $uniqueID = md5(uniqid(rand())); ?>
<form name="upload" onsubmit="javascript:uploadFile();" action="upload.php" target="upload_target" method="post" id="ajax_upload" enctype="multipart/form-data">
        <input type="file" name="myfile" id="myfile"/><br />
        <input type="hidden" name="APC_UPLOAD_PROGRESS" id="progress_key" value="<?php echo $uniqueID; ?>" />
<input type="submit" value="Upload" />
</form>
<div id="progress"></div>

<iframe id="upload_target" name="upload_target" style="width:0;height:0;border:0px solid #fff;"></iframe>

There is our basic form, it is very important to leave the name of the apc input the way it is. Notice there is a DIV with the id of “progress”, this is the area we will display the upload progress. We are also including a hidden iframe so that the form will post there and not refresh the page. Also take note of the function call in the form tag, the onsubmit calls our JavaScript function to track the upload, we will write this later.

Now lets set up some of the JavaScript and Ajax. In order for us to tell if something is being posted back to us from any of our scripts we must listen for them. We have two different types of listeners here, one for IE and another for most other browsers.

Listener

var HttpListener = false;
if(window.XMLHttpRequest) {
        HttpListener = new XMLHttpRequest();
}
else if(window.ActiveXObject) {
        HttpListener = new ActiveXObject("Microsoft.XMLHTTP");
}

We will use the above listener in our progress function.

Progress Function

function Progress(uniqueID) {
   if(HttpListener) {
      HttpListener.open(‘GET’, ‘get_progress.php?uniqueID=’ + uniqueID, true);
      HttpListener.onreadystatechange = function() {
         if(HttpListener.readyState == 4 && HttpListener.status == 200) {
            var response = HttpListener.responseText;
                        if (isNaN(response)){response=1; }
            document.getElementById(‘progress’).innerHTML = Math.round(response) + "%";
            if(response < 100) {
               setTimeout(‘getProgress(‘+"’"+uniqueID+"’"+‘)’, 100);
            }
            else {
                       document.getElementById(‘progress’).innerHTML = "100% – Upload Complete!";
            }
         }
      }
      HttpListener.send(null);
   }
}

What the above function does is send the uniqueID that we generated in the form to a file called get_progress.php(which we will write in a sec.) and listens for a response. When we receive a response from that file we update the results in our DIV progress back on our main page. You also see the “setTimeout” function, this calls the function over and over again which essentially posts to get_progress again and again thus updating our progress.

In order for this all to work we need one last piece of JavaScript, the actual function that sets the ball in motion:

function uploadFile(){
        var uniqueID = document.getElementById(‘progress_key’).value;
        setTimeout(‘Progress("’ + uniqueID + ‘")’, 500);
}

This function grabs the uniqueID from the hidden input on the page and passes the value to our Progress function after half a second.

Progress:
The get_progress.php file mentioned above is very simple, here it is:

header(‘Expires: Mon, 26 Jul 1997 05:00:00 GMT’);
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header(‘Cache-Control: no-store, no-cache, must-revalidate’);
header(‘Cache-Control: post-check=0, pre-check=0′, FALSE);
header(‘Pragma: no-cache’);
if(isset($_GET[‘uniqueID’])){
   $progress = apc_fetch(‘upload_’ . $_GET[‘uniqueID’]);
   echo round($progress[‘current’]/$progress[‘total’]*100);
}

The get_progress.php file simply takes the uniqueID and calls the apc_fetch function which reports back an array of data about the file it is tracking. We are using “current” and “total” to come up with our percentage. The first four lines of this is to prevent some browsers from caching the original request, we force those to update each time this is called, otherwise the bar would appear frozen.

Last but not least, you need an upload.php script which will actually handle the file transfer, three lines and you are done:

$filepath = "uploads/";
$filepath = $filepath . basename( $_FILES[‘myfile’][‘name’]);
move_uploaded_file($_FILES[‘myfile’][‘tmp_name’], $filepath);

And that is it. When you break this code into sections and actually read how it all works, life becomes easy and this project becomes simple.

A note for those of you looking for a progress bar, the response sent from our get_progress.php is simply a number from 1 to 100. So you could take that number to create a very simple upload bar by creating a container DIV set to a width of 100px and place another container inside of that one set to an initial width of 0. You will need the internal div color to be set to whatever color you would like your bar and use JavaScript to update the inner div width based on the response.

For a progress bar on another site I used an animated gif as the background of my outer DIV and overlaid it with a transparent gif of the same dimensions for a really nice effect.

You can download the full source for this by clicking here. But I strongly recommend you read this entire article!
Good luck and have fun with this one.

4,328 Responses to “PHP File Upload Progress (APC Fetch PECL)”

  1. Comment…

    I enjoy reading a post that will make people think. Also, thanks for allowing me to comment!…

  2. Read was interesting, stay in touch……

    [...] listed here you will find the link to a few sites that we think you must see [...]…

  3. Favorite webpage…

    [...] Blogpost: article .. found this article with regards to [...]…

  4. Great information…

    This is fantastic. Individuals watch the promise blog posts and we are astonished. We are fascinated by this kind of clothes. Individuals appreciate his memo, and profit doing inside this. Please keep editing. They may be entirely much needed informati…

  5. Play Games says:

    outside path…

    areas such as fighting, capturing, schooling, jigsaw, racing, arcades, and even adventure….

  6. Ear plugs…

    Have been following your blog for a while now. Well done on helping farmers in developing countries. Ca nyou please elaborate on what you meant by helping the niave become more professional….

  7. forex bonus says:

    Sites we Like……

    [...] Every once in a while we choose blogs that we read. Listed below are the latest sites that we choose [...]……

  8. your opinions…

    onto others, you should utilize online video games which can be found for free to identify the talents of…

  9. [...]always a big fan of linking to bloggers that I love but don’t get a lot of link love from[...]……

    [...]just beneath, are numerous totally not related sites to ours, however, they are surely worth going over[...]……

  10. Dreary Day…

    It was a dreary day here yesterday, so I just took to piddeling around on the internet and realized…

  11. [...]The information mentioned in the article are some of the best available [...]……

    [...]below you’ll find the link to some sites that we think you should visit[...]……

  12. Cool Games says:

    both found…

    yourself and have the energy which might make you progress to another level….

  13. sbobet says:

    Hey…

    Outstanding post, I conceive website owners should learn a lot from this site its really user pleasant. So much great info on here :D ….

  14. [...]always a big fan of linking to bloggers that I love but don’t get a lot of link love from[...]……

    [...]just beneath, are numerous totally not related sites to ours, however, they are surely worth going over[...]……

  15. Insulated Concrete Forms…

    [...]that would be the finish of this write-up. Right here you?ll discover some web-sites that we feel you?ll enjoy, just click the links over[...]…

  16. spending to…

    which contain capturing provide children with alternative to see and imagine the type of injury sure actions may cause to property and life….

  17. Luxury Home says:

    Luxury Home…

    [...]The information and facts mentioned inside the article are a number of the best obtainable [...]…

  18. Much Thanks!…

    Thanks for taking the time to provide us all with the info!…

  19. alone. many people suffer from this problem…

    and spend thousands of dollars in surgical procedures and spa treatments to get rid of the problem. the good news is that you can get rid of it, and you do not have to spend thousands of dollars. there is a…

  20. tire deals says:

    a new tire plant in southeast asia….

    cooper will add usd 10 million to improve the automatic production level of its tire plants; meanwhile it declares to improve the production capacity of its plant in texarkana and expand the production facilities in arkansas and mississippi of usa, gua…

  21. provide our immune system with the necessary…

    tools to fight bacteria and viruses, vibrant health will always be the natural result.the typical processed food diet is void of the nutrients we require to fuel our immune system and we become a magnet for a host of circulating pathogens…

  22. {Websites|Web sites|Sites|Internet sites|Internet websites|Web pages} {you should|you need to|you ought to|you must|it is best to|you’ll want to} visit……

    [...]below you will discover the link to some web-sites that we consider you ought to visit[...]…

  23. Coolest news on earth, you have to see this!…

    [...] normally posts some very interesting stuff like this. If you’re new to this page [...]…

  24. Film location in turkey…

    [...]We can provide locations to be used in still photography, television and film productions. With your brief our location management crew researches the best places for you and presents an offering report.[...]……

  25. Check this out…

    [...] that is the end of this article. Here you’ll find some sites that we think you’ll appreciate, just click the links over[...]……

  26. 2011…

    Just desire to say your article is as amazing. The clearness in your post is just nice and i can assume you’re an expert on this subject. Well with your permission let me to grab your feed to keep up to date with forthcoming post. Thanks a million and…

Leave a Reply

Spam protection by WP Captcha-Free

About Me

I am an independent web developer and webmaster of many sites. The main goal of Script Perfect is to provide answers to some of the hard to find questions when it comes to website design and coding.

Twitter