Session 上传进度

session.upload_progress.enabled INI 选项开启时,PHP 能够在每一个文件上传时监测上传进度。 这个信息对上传请求自身并没有什么帮助,但在文件上传时应用可以发送一个POST请求到终端(例如通过XHR)来检查这个状态

当一个上传在处理中,同时POST一个与INI中设置的session.upload_progress.name同名变量时,上传进度可以在$_SESSION中获得。 当PHP检测到这种POST请求时,它会在$_SESSION中添加一组数据, 索引是 session.upload_progress.prefixsession.upload_progress.name连接在一起的值。 通常这些键值可以通过读取INI设置来获得,例如

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

通过将$_SESSION[$key]["cancel_upload"]设置为TRUE,还可以取消一个正在处理中的文件上传。 当在同一个请求中上传多个文件,它仅会取消当前正在处理的文件上传和未处理的文件上传,但是不会移除那些已经完成的上传。 当一个上传请求被这么取消时,$_FILES中的error将会被设置为 UPLOAD_ERR_EXTENSION

session.upload_progress.freqsession.upload_progress.min_freq INI选项控制了上传进度信息应该多久被重新计算一次。 通过合理设置这两个选项的值,这个功能的开销几乎可以忽略不计。

Example #1 样例信息

一个上传进度数组的结构的例子

<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>

在session中存放的数据看上去是这样子的:

<?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// Amount 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

为了使这个正常工作,web服务器的请求缓冲区需要禁用,否则 PHP可能仅当文件完全上传完成时才能收到文件上传请求。 已知会缓冲这种大请求的程序有Nginx。

add a note add a note

User Contributed Notes 15 notes

up
70
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.
up
15
gerd dot randolf at web dot de
3 years ago
Note that this will be available from PHP 5.4 on. It won't work in PHP 5.3 or earlier.
up
8
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.
up
2
howtomakeaturn
4 months 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!
up
11
isius
2 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.
up
1
ricki at rocker dot com
4 months ago
session.upload_progress updates completely ignore custom session handlers set via  session_set_save_handler()
up
1
StrateGeyti
10 months 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.
up
3
wojbach at o2 dot pl
3 years ago
"session.upload-progress.name" -> whether here shouldn't be a underscore instead of a dash
up
2
Anonymous
2 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.
up
0
wilsonr at st dot com
10 months 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;" ... />
up
-4
jortsc at gmail dot com
1 year 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].
up
-5
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.
up
-17
takeone
3 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.
up
-29
micheal_jordan at rocketmail dot com
1 year ago
It also be noted that dhinka chika, dhinka chika, ae ae. Other wise none of the $_SESSION super global variable will get any of the information related to uploading. Always define global $hoogalala before initializing any upload form.
To Top