Upload Progress Bar using Php and Dojo

For a long time I have wanted my applications to have progress bars on uploads, but I have always thought that this was impossible when the server language was php. Unless of course you wanted to do some mixing of languages, and handle the upload via perl. I, however, wanted complete integration of the code, and wanted my mvc framework to be able to output the wanted information. A while ago my boss at Voicearchive asked me if we could get a progress bar for uploads on the system that we are developing. Once again I found myself searching for possible solutions.

This time around, however, I found what I was looking for. I found an article about PHP and jQuery upload progress bar. In this article I learned about the PECL extension uploadprogress. I began trying to make this solution work.

First thing, was that I found the extension did not work as I wanted. After a while I found that installing newest version, required installing it via “pecl install channel://pecl.php.net/uploadprogress-0.9.2″ – which gave me the latest beta release of the extension. Now it returned the correct information when I uploaded a file.

The solution consists of 5 parts.

  1. The Pecl extension
  2. The form
  3. The progressbar widget
  4. The javascript
  5. and the controller which sends the data from uploadprogress as json to the client

After the installation was managed, I changed the form to have the required hidden UPLOAD_IDENTIFIER value included.


The value of the field is set when the dialogbox containing the upload form is revealed, and saved in a variable, that can be used when the script needs to poll for the result.

lastFileProgressKey = guid();
console.log(lastFileProgressKey);
dojo.byId('addFileProgressKey').value = lastFileProgressKey;
dijit.byId('addFileDialog').show();

The guid function is just a simple function which generates a guid-like random string. The value is then set to the form, and the dialog is revealed.

When the upload button on the form is pressed it calls a event handler which handles the actual upload. Before the upload is started however the following function is called.

startUploadCheck(lastFileProgressKey);

These function do the actual work.

function updateProgressBar(response) {
	if(response) {
		totalBytes = parseInt(response.bytes_total);
		uploadedBytes = parseInt(response.bytes_uploaded);
		percentage = Math.floor(100 * uploadedBytes/ totalBytes);
		uploadProgressBar.update({ progress: percentage+'%'});
		if(lastUploadId!='') {
			setTimeout("checkUpload()", 1000);
		}
	} else {
		if(lastUploadId!='') {
			setTimeout("checkUpload()", 1000);
		}
	}
}

function checkUpload() {
	dojo.xhrGet( {
		url :'/uploadprogress/check?uploadid='+lastUploadId,
		handleAs: 'json',
		preventCache: true,
		load: updateProgressBar,
		error: function(data) {
			if(lastUploadId!='') {
				setTimeout("checkUpload()", 1000);
			}
		}
	});
}

function startUploadCheck(uploadid) {
	dijit.byId('uploadProgressDialog').show();
	lastUploadId = uploadid;
	checkUpload( uploadid );
}

function hideProgressDialog() {
	lastUploadId = '';
	dijit.byId('uploadProgressDialog').hide();
}

The dojo widget used is the ProgressBar.

The controller is the simplest part of the equation.

public function check() {
    $formUploadId = $this->request['uploadid'];
    return json_encode(uploadprogress_get_info($formUploadId));
}

All the legwork is done by uploadprogress_get_info, which then is passed through json_encode.

by Claus Witt

February 25, 2009  Tags: , ,   Posted in: Development, Web development