Press "Enter" to skip to content

Upload Progress Support (Upload Progress in Sessions)

Upload progress feedback is a requirement that has become increasingly common, for example in mail with large attachments. Before PHP 5.4, we could implement this using the feature provided by APC, or by using the PECL extension uploadprogress.
Although they solve the current problem well, they also have some obvious drawbacks:

  • 1. They all require an extra install (we were not planning to add APC to PHP 5.4).
  • 2. They all use a local mechanism to store this information: APC uses shared memory, while uploadprogress uses the file system (NFS not considered). This becomes troublesome when you have multiple front-end machines.

From PHP's point of view, the best place to store this information should be the SESSION. First, it is a mechanism natively supported by PHP. Second, it can be configured to be stored anywhere (supporting multi-machine sharing).
Precisely for this reason, Arnaud Le Blanc proposed an RFC for reporting upload progress via the Session, and the implementation is now included in the PHP 5.4 trunk.
This new feature provides some new INI settings, which are similar to APC's corresponding settings:

  • session.upload_progress.enabled[=1] : whether to enable upload progress reporting (enabled by default)
  • session.upload_progress.cleanup[=1] : whether to delete the progress data promptly after the upload completes (enabled by default, recommended).
  • session.upload_progress.prefix[=upload_progress_] : the progress data is stored in $_SESSION[session.upload_progress.prefix . $_POST[session.upload_progress.name]]
  • session.upload_progress.name[=PHP_SESSION_UPLOAD_PROGRESS] : if $_POST[session.upload_progress.name] is not set, no progress will be reported.
  • session.upload_progress.freq[=1%] : the frequency of updating the progress (the number of bytes processed); it also supports a percentage form '%'.
  • session.upload_progress.min_freq[=1.0] : the time interval for updating the progress (in seconds)

For the following upload form:

<form action="upload.php" method="POST" enctype="multipart/form-data">
 <input type="hidden"
     name="<?php echo ini_get("session.upload_progress.name"); ?>" value="laruence" />
 <input type="file" name="file1" />
 <input type="file" name="file2" />
 <input type="submit" />
</form>

If we upload a large enough file (it'd be even better if the network is slow enough :P), we can get progress information like the following from $_SESSION:

$_SESSION["upload_progress_laruence"] = array(
 "start_time" => 1234567890,   // request time
 "content_length" => 57343257, // total size of the uploaded file
 "bytes_processed" => 453489,  // size processed so far
 "done" => false,              // TRUE once all uploads are finished
 "files" => array(
  0 => array(
   "field_name" => "file1",       // the name of the upload field in the form
   // The following 3 elements equal those in $_FILES
   "name" => "foo.avi",
   "tmp_name" => "/tmp/phpxxxxxx",
   "error" => 0,
   "done" => true,                // becomes TRUE once this file is processed
   "start_time" => 1234567890,    // the time this file started processing
   "bytes_processed" => 57343250, // the size of this file processed so far
  ),
  // Another file, not finished uploading, in the same request
  1 => array(
   "field_name" => "file2",
   "name" => "bar.avi",
   "tmp_name" => NULL,
   "error" => 0,
   "done" => false,
   "start_time" => 1234567899,
   "bytes_processed" => 54554,
  ),
 )
);

Isn't that convenient?
That said, a reminder: PHP 5.4 is still under development. Before the final release, any new feature may be adjusted or changed. If you have any suggestions, feedback is welcome, to help make PHP even better.
Thanks
Johannes' blog also introduced it: http://schlueters.de/blog/archives/151-Upload-Progress-in-PHP-trunk.html
For more updates, follow: Changelog

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.