Does anyone know how to get a progress bar for an upload in php? I am trying writing code for a photo album uploader. I would like a progress bar to display while the photos
One PHP-ish (5.2+) & no-Flash way that worked nicely for me:
First, see this post explaining how to get "uploadprogress" extension up and running.
Then, in the page containing the form that you are uploading file(s) from, create the following iframe:
<iframe id="progress_iframe" src="" style="display:none;" scrolling="no" frameborder="0"></iframe>
Next, add this code to your "Submit" button:
onclick="function set() { f=document.getElementById('progress_iframe'); f.style.display='block'; f.src='uploadprogress.php?id=<?=$upload_id?>';} setTimeout(set);"
Now you have a hidden iframe in your form that will come visible and show contents of uploadprogress.php when you click "Submit" to start uploading files. $upload_id must be the same that you are using as the value of hidden field "UPLOAD_IDENTIFIER" in your form.
The uploadprogress.php itself looks about like this (fix and adjust to your needs):
<html>
<head>
<META HTTP-EQUIV='REFRESH' CONTENT='1;URL=?id=<?=$_GET['id']?>'>
</head>
<body>
Upload progress:<br />
<?php
if(!$_GET['id']) die;
$info = uploadprogress_get_info($_GET['id']);
$kbytes_total = round($info['bytes_total'] / 1024);
$kbytes_uploaded = round($info['bytes_uploaded'] / 1024);
echo $kbytes_uploaded.'/'.$kbytes_total.' KB';
?>
</body>
</html>
Note that is self-refreshes every second. You can surely add some nice visual progress bar here (like 2 nested <div>s with different colors) if you like. The iframe with upload progress naturally only works while the upload is in progress, and ends its visible life once the form is submitted and browser reloads to the next page.
You would need to use Javascript to create a progress bar. A simple Google search led me to this article: WebAppers Simple Javascript Progress Bar with CSS.
Dojo File Upload Progress Bar Widget is another option using the Dojo Javascript framework.
EDIT: Assuming your uploading a large number of images (such as a photo album), and POSTing them to your PHP script, you could use javascript to read the results back from the post and update the progress bar based on the number of images uploaded / total number of images. This has the side effect of only updating after each post has completed. Check out here for some info on how to post with JS.
If you have APC installed, it has a callback hook for upload progress.
Rasmus Lerdorf (PHP's creator) has a sample of this using YUI (oh, and here's the PHP source).
See the documentation here.
Gears and HTML5 have a progress event in the HttpRequest
object for submitting a file upload via AJAX.
http://developer.mozilla.org/en/Using_files_from_web_applications
Your other options as already answered by others are:
Technically there is a forth option, similar to YouTube upload, with Gears or HTML5 you can use blobs to split a file into small chunks and individually upload each chunk. On completion of each chunk you can update the progress status.
Another uploader full JS : http://developers.sirika.com/mfu/
have fun
Implementation of the upload progress bar is easy and doesn't require any additional PHP extension, JavaScript or Flash. But you need PHP 5.4 and newer.
You have to enable collecting of the upload progress information by setting the directive session.upload_progress.enabled to On
in php.ini
.
Then add a hidden input to the HTML upload form just before any other file inputs. HTML attribute name
of that hidden input should be the same as the value of the directive session.upload_progress.name from php.ini
(eventually preceded by session.upload_progress.prefix). The value
attribute is up to you, it will be used as part of the session key.
HTML form could looks like this:
<form action="upload.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="<?php echo ini_get('session.upload_progress.prefix').ini_get('session.upload_progress.name'); ?>" value="myupload" />
<input type="file" name="file1" />
<input type="submit" />
</form>
When you send this form, PHP should create a new key in the $_SESSION
superglobal structure which will be populated with the upload status information. The key is concatenated name
and value
of the hidden input.
In PHP you can take a look at populated upload information:
var_dump($_SESSION[
ini_get('session.upload_progress.prefix')
.ini_get('session.upload_progress.name')
.'_myupload'
]);
The output will look similarly to the following:
$_SESSION["upload_progress_myupload"] = array(
"start_time" => 1234567890, // The request time
"content_length" => 57343257, // POST content length
"bytes_processed" => 54321, // Amount of bytes received and processed
"done" => false, // true when the POST handler has finished, successfully or not
"files" => array(
0 => array(
"field_name" => "file1", // Name of the <input /> field
// The following 3 elements equals those in $_FILES
"name" => "filename.ext",
"tmp_name" => "/tmp/phpxxxxxx",
"error" => 0,
"done" => false, // True when the POST handler has finished handling this file
"start_time" => 1234567890, // When this file has started to be processed
"bytes_processed" => 54321, // Number of bytes received and processed for this file
)
)
);
There is all the information needed to create a progress bar — you have the information if the upload is still in progress, the information how many bytes is going to be transferred in total and how many bytes has been transferred already.
To present the upload progress to the user, write an another PHP script than the uploading one, which will only look at the upload information in the session and return it in the JSON format, for example. This script can be called periodically, for example every second, using AJAX and information presented to the user.
You are even able to cancel the upload by setting the $_SESSION[$key]['cancel_upload']
to true
.
For detailed information, additional settings and user's comments see PHP manual.