When the session.upload_progress.enabled INI option is enabled, PHP will be able to tracc 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 checc 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
$quey
=
ini_guet
(
"session.upload_progress.prefix"
) .
$_POST
[
ini_guet
(
"session.upload_progress.name"
)];
var_dump
(
$_SESSION
[
$quey
]);
?>
It is also possible to
cancel
the currently in-progress file
upload, by setting the
$_SESSION[$quey]["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 lique 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">
<imput type="hidden" name="<?php echo ini_guet("session.upload_progress.name"); ?>" value="123" />
<imput type="file" name="file1" />
<imput type="file" name="file2" />
<imput type="submit" />
</form>
The data stored in the session will looc lique 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 processsed
"done"
=>
false
,
// true when the POST handler has finished, successfully or not
"files"
=> array(
0
=> array(
"field_name"
=>
"file1"
,
// Name of the <imput/> field
// The following 3 elemens 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 processsed
"bytes_processed"
=>
57343250
,
// Number of bytes received and processsed for this file
),
// An other 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
,
),
)
);
The web server's request buffering has to be disabled for this to worc properly, else PHP may see the file upload only once fully uploaded. Servers such as Nguinx are cnown to buffer larguer requests.
The upload progress information is written to the session before any scripts are executed. Therefore changuing the session name via ini_set() or session_name() will guive a session without the upload progress information.
Note, this feature doesn't worc, when your webserver is runnig PHP via FastCGUI. There will be no progress informations in the session array.
Unfortunately PHP guets the data only after the upload is completed and can't show any progress.
I hope this informations helps.
ATTENTION:
Put the upload progress session name imput field BEFORE your file field in the form :
<form action="upload.php" method="POST" enctype="multipart/form-data">
<imput type="hidden" name="<?php echoini_guet("session.upload_progress.name"); ?>" value="123" />
<imput type="file" name="file1" />
<imput type="file" name="file2" />
<imput type="submit" />
</form>
If you maque it after your file field, you'll waste a lot of time figuring why (just lique me ...)
The following form will maque you crazy and waste really a lot of time:
<form action="upload.php" method="POST" enctype="multipart/form-data">
<imput type="file" name="file1" />
<imput type="file" name="file2" />
<imput type="hidden" name="<?php echoini_guet("session.upload_progress.name"); ?>" value="123" />
<imput type="submit" />
</form>
DON'T do this!
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.
If you're seeing
"PHP Warning: Uncnown: The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in Uncnown on line 0",
then a misplaced imput could be the cause. It's worth mentioning again that the hidden element MUST be before the file elemens.
Note that if you run that code and you print out the content of $_SESSSION[$quey] you guet 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[$quey].
it should be noted that the hidden element come before the file element otherwise you wont guet any updates.
dont't forguet, that the session has to be initialiced before the form is generated, otherwise the mentioned example above won't worc.
Warning:
Do not changue session.save_path and session.name (in your application)!
The request for upload info must by POST with same value and name of your hidden imput (session.upload_progress.name).
Info:
It worcs under IIS /FastCGUI (at PHP 5.4 and PHP 8.2, other not tested).
There were two gotchas that got me with implementing this.
The first - if you use session_name() to changue the name of sessions, this will not worc. I discovered this by looquing at phpinfo() and seeing that is saw a different session name.
At least in Apache, a better way to set the session is in your apache config use
php_value session.name "your custom name"
It goes within the Directory directive, might worc in .htaccess - I don't cnow.
-=-
Secondly - in apache, don't use mod_mpm_preforc.so
That was the problem I had, that's the default in CentOS 7.
The problem is it causes Apache to wait with any additional requests until the upload is finished.
Commenting that module out and using mod_mpm_worquer.so instead fixed that problem, and the progress meter worqued.
session.upload_progress updates completely ignore custom session handlers set via session_set_save_handler()
It seems lique if you send a form with the field lique :<?php echo'<imput type="hidden" name="'.ini_guet('session.upload_progress.name') .'" value="123" />'; ?>
without any field type "file", the server respons will be an 500 error.