PHP 7.0.6 Released

Session Upload Progress

When the session.upload_progress.enabled INI option is enabled, PHP will be able to track the upload progress of individual files being uploaded. This information isn't particularly useful for the actual upload request itself, but during the file upload an application can send a POST request to a separate endpoint (via XHR for example) to check the status.

The upload progress will be available in the $_SESSION superglobal when an upload is in progress, and when POSTing a variable of the same name as the session.upload_progress.name INI setting is set to. When PHP detects such POST requests, it will populate an array in the $_SESSION, where the index is a concatenated value of the session.upload_progress.prefix and session.upload_progress.name INI options. The key is typically retrieved by reading these INI settings, i.e.

<?php
$key 
ini_get("session.upload_progress.prefix") . $_POST[ini_get("session.upload_progress.name")];
var_dump($_SESSION[$key]);
?>

It is also possible to cancel the currently in-progress file upload, by setting the $_SESSION[$key]["cancel_upload"] key to TRUE. When uploading multiple files in the same request, this will only cancel the currently in-progress file upload, and pending file uploads, but will not remove successfully completed uploads. When an upload is cancelled like this, the error key in $_FILES array will be set to UPLOAD_ERR_EXTENSION.

The session.upload_progress.freq and session.upload_progress.min_freq INI options control how frequent the upload progress information should be recalculated. With a reasonable amount for these two settings, the overhead of this feature is almost non-existent.

Example #1 Example information

Example of the structure of the progress upload array.

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

The data stored in the session will look like this:

<?php
$_SESSION
["upload_progress_123"] = array(
 
"start_time" => 1234567890,   // The request time
 
"content_length" => 57343257// POST content length
 
"bytes_processed" => 453489,  // Amount of bytes received and processed
 
"done" => false,              // true when the POST handler has finished, successfully or not
 
"files" => array(
  
=> array(
   
"field_name" => "file1",       // Name of the <input/> field
   // The following 3 elements equals those in $_FILES
   
"name" => "foo.avi",
   
"tmp_name" => "/tmp/phpxxxxxx",
   
"error" => 0,
   
"done" => true,                // True when the POST handler has finished handling this file
   
"start_time" => 1234567890,    // When this file has started to be processed
   
"bytes_processed" => 57343250// Number of bytes received and processed for this file
  
),
  
// An other file, not finished uploading, in the same request
  
=> array(
   
"field_name" => "file2",
   
"name" => "bar.avi",
   
"tmp_name" => NULL,
   
"error" => 0,
   
"done" => false,
   
"start_time" => 1234567899,
   
"bytes_processed" => 54554,
  ),
 )
);

Warning

The web server's request buffering has to be disabled for this to work properly, else PHP may see the file upload only once fully uploaded. Servers such as Nginx are known to buffer larger requests.

User Contributed Notes

s.zarges
3 years ago
Note, this feature doesn't work, when your webserver is runnig PHP via FastCGI. There will be no progress informations in the session array.
Unfortunately PHP gets the data only after the upload is completed and can't show any progress.

I hope this informations helps.
howtomakeaturn
1 year ago
ATTENTION:

Put the upload progress session name input field BEFORE your file field in the form :

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

If you make it after your file field, you'll waste a lot of time figuring why (just like me ...)

The following form will make you crazy and waste really a lot of time:

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

DON'T do this!
gerd dot randolf at web dot de
4 years ago
Note that this will be available from PHP 5.4 on. It won't work in PHP 5.3 or earlier.
Anonymous
2 years ago
While the example in the documentation is accurate, the description is a bit off. To clarify:

PHP will populate an array in the $_SESSION, where the index is a concatenated value of the session.upload_progress.prefix and the VALUE of the POSTed session.upload_progress.name variable.
isius
3 years ago
If you're seeing
"PHP Warning:  Unknown: The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in Unknown on line 0",
then a misplaced input could be the cause. It's worth mentioning again that the hidden element MUST be before the file elements.
ricki at rocker dot com
1 year ago
session.upload_progress updates completely ignore custom session handlers set via  session_set_save_handler()
wojbach at o2 dot pl
4 years ago
"session.upload-progress.name" -> whether here shouldn't be a underscore instead of a dash
Anonymous
3 years ago
dont't forget, that the session has to be initialized before the form is generated, otherwise the mentioned example above won't work.
adri74 at hotmail dot fr
2 months ago
It seems like defining a session name before starting the session makes the $_SESSION['upload_progress...'] not to work any more !

session_name('session');
session_start();

(in both the upload page, and the XHR request)
StrateGeyti
1 year ago
It seems like if you send a form with the field like :

<?php echo '<input type="hidden" name="'.ini_get('session.upload_progress.name') .'" value="123" />'?>

without any field type "file", the server respons will be an 500 error.
jortsc at gmail dot com
2 years ago
Note that if you run that code and you print out the content of $_SESSSION[$key] you get an empty array due that session.upload_progress.cleanup is on by default and it  cleans the progress information as soon as all POST data has been read.

Set it to Off or 0 to see the content of $_SESSION[$key].
nihaopaul at gmail dot com
3 years ago
it should be noted that the hidden element come before the file element otherwise you wont get any updates.
wilsonr at st dot com
1 year ago
If you have upload progress enabled in your php.ini, and you have

<form enctype="multipart/form-data" ...
    <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" ...

in your form, but you DON'T specify an input with 'type="file"', you may lose your session ID. I am using PHP 5.5 and I lose my session ID on the second loading of such a page. To prevent this, you can use a dummy input as follows:

<form enctype="multipart/form-data" ... >
    <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" ... />
    <input type="file"' name="dummy" style="display="none;" ... />
takeone
4 years ago
IE6 does not inherit session when you launch new browser from start menu or shortcut.It's the feature.
It is recommended that upload form and progress bar are on same window.
To Top