Progression d'un téléversement (upload) en session

Lorsque l'option de configuration session.upload_progress.enabled est active, PHP sera capable de traquer la progression d'un fichier en cours de tĂ©lĂ©versement (upload). Cette information n'est pas particuliĂšrement utile pour la requĂȘte de tĂ©lĂ©versement en tant que tel, mais pendant le tĂ©lĂ©versement, une application peut envoyer une requĂȘte POST sĂ©parĂ©e (via XHR par exemple) pour vĂ©rifier le statut de ce tĂ©lĂ©versement.

La progression du tĂ©lĂ©versement sera disponible dans la variable super-globale $_SESSION lorsque le tĂ©lĂ©versement est en cours, et lors d'un envoi en mĂ©thode POST d'une variable du mĂȘme nom que celui dĂ©fini dans l'option de configuration INI session.upload_progress.name. Lorsque PHP dĂ©tecte une requĂȘte POST de ce type, il remplira un tableau dans $_SESSION, oĂč l'index est une valeur concatĂ©nĂ©e des options de configuration session.upload_progress.prefix et session.upload_progress.name. La clĂ© est typiquement rĂ©cupĂ©rĂ©e en lisant ces configurations INI, c.-Ă -d.

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

Il est Ă©galement possible d'annuler le tĂ©lĂ©versement courant en dĂ©finissant la clĂ© $_SESSION[$key]["cancel_upload"] Ă  la valeur true. Lors du tĂ©lĂ©versement de plusieurs fichiers dans la mĂȘme requĂȘte, cette action n'annulera que le fichier actuellement en cours de tĂ©lĂ©chargement, ainsi que ceux en attente de tĂ©lĂ©versement mais n'annulera pas les tĂ©lĂ©versements terminĂ©s avec succĂšs. Lorsqu'un tĂ©lĂ©versement est annulĂ© en utilisant cette mĂ©thode, la clĂ© error du tableau $_FILES sera dĂ©finie Ă  UPLOAD_ERR_EXTENSION.

Les options de configuration INI session.upload_progress.freq et session.upload_progress.min_freq contrÎlent la fréquence de mise à jour des informations de progression de téléversement. Avec une configuration raisonnable de ces 2 options, le surcoût en terme de charge est quasi nul.

Exemple #1 Exemple

Exemple de structure du tableau contenant les informations de téléversement.

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

Les données stockées en session ressembleront à :

<?php
$_SESSION
["upload_progress_123"] = array(
"start_time" => 1234567890, // L'heure de la requĂȘte
"content_length" => 57343257, // Longueur du contenu POST
"bytes_processed" => 453489, // Quantité d'octets reçus et traités
"done" => false, // true lorsque le gestionnaire POST a terminé, avec succÚs ou non
"files" => array(
0 => array(
"field_name" => "file1", // Nom du champ <input/>
// Les 3 éléments suivants sont équivalents à ceux dans $_FILES
"name" => "foo.avi",
"tmp_name" => "/tmp/phpxxxxxx",
"error" => 0,
"done" => true, // True lorsque le gestionnaire POST a terminé de gérer ce fichier
"start_time" => 1234567890, // L'heure de dĂ©but de requĂȘte
"bytes_processed" => 57343250, // Quantité d'octets reçus et traités pour ce fichier
),
// Un autre fichier, en cours de tĂ©lĂ©versement, dans la mĂȘme requĂȘte
1 => array(
"field_name" => "file2",
"name" => "bar.avi",
"tmp_name" => NULL,
"error" => 0,
"done" => false,
"start_time" => 1234567899,
"bytes_processed" => 54554,
),
)
);
Avertissement

La mise en mĂ©moire tampon de la requĂȘte du serveur web doit ĂȘtre dĂ©sactivĂ©e pour la bonne marche de cette fonctionnalitĂ©, sinon PHP ne verra le fichier qu'une fois qu'il sera totalement tĂ©lĂ©versĂ©. Les serveurs tels que Nginx sont connus pour mettre en mĂ©moire tampon des grosses requĂȘtes.

Attention

Les informations de la progression du téléversement sont écrites en session avant qu'un script soit exécuté. Par conséquent, changer le nom de session grùce à ini_set() ou session_name() donnera une session sans les informations de progression du téléversement.

add a note

User Contributed Notes 11 notes

up
165
s.zarges ¶
13 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
63
howtomakeaturn ¶
11 years 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
25
Anonymous ¶
13 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
13
isius ¶
13 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
7
jortsc at gmail dot com ¶
12 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].
up
5
nihaopaul at gmail dot com ¶
13 years ago
it should be noted that the hidden element come before the file element otherwise you wont get any updates.
up
4
Anonymous ¶
13 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
1
raptor98 at email dot cz ¶
1 year ago
Warning:
Do not change 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 input (session.upload_progress.name).

Info:
It works under IIS /FastCGI (at PHP 5.4 and PHP 8.2, other not tested).
up
0
alice at librelamp dot com ¶
9 years ago
There were two gotchas that got me with implementing this.

The first - if you use session_name() to change the name of sessions, this will not work. I discovered this by looking 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 work in .htaccess - I don't know.

-=-

Secondly - in apache, don't use mod_mpm_prefork.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_worker.so instead fixed that problem, and the progress meter worked.
up
0
ricki at rocker dot com ¶
11 years ago
session.upload_progress updates completely ignore custom session handlers set via  session_set_save_handler()
up
0
StrateGeyti ¶
11 years 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.