# Fortschritt eines Uploads in einer Session

Wenn die Ini-Option session.upload_progress.enabled aktiviert ist, kann PHP den Upload-Fortschritt der einzelnen hochgeladenen Dateien verfolgen. Die von PHP bereitgestellten Daten sind für den eigentlichen Upload-Vorgang selbst nicht nutzbar, aber während des Datei-Uploads kann eine Anwendung eine POST-Anfrage an einen separaten Endpunkt senden (z. B. über XHR), um den Status zu ermitteln.

Der Upload-Fortschritt steht während des Upload-Vorgangs in der Superglobalen $_SESSION zur Verfügung und bei einer POST-Anfrage nach der Variablen mit dem in der ini-Konfiguration session.upload_progress.name hinterlegten Namen. Wenn PHP eine solche POST-Anfrage erkennt, wird ein Array mit Informationen in der $_SESSION hinterlegt. Die Informationen werden mit dem aus den ini-Konfigurationen session.upload_progress.prefix und session.upload_progress.name zusammengesetzten Index gespeichert. Der Schlüssel wird dabei typischerweise aus den ini-Konfigurationen zusammengesetzt, zum Beispiel:

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

Es ist auch möglich, den Upload-Vorgang abzubrechen, indem der Session-Wert `$_SESSION[$key]["cancel_upload"]` auf `true` gesetzt wird. Wenn mehrere Dateien in der gleichen Anfrage übertragen werden, werden dabei nur der Upload der in der Verarbeitung befindlichen Datei und alle ausstehenden Datei-Uploads abgebrochen. Bereits erfolgreich übertragene Dateien werden nicht entfernt. Wenn ein Upload auf diese Weise abgebrochen wird, enthält der `error`-Schlüssel des $_FILES-Arrays den Wert `UPLOAD_ERR_EXTENSION`.

Die Ini-Konfigurationen session.upload_progress.freq und session.upload_progress.min_freq steuern, wie häufig die Upload-Fortschrittsinformationen neu berechnet werden sollen. Mit angemessenen Einstellungen bei diesen zwei Optionen ist der Aufwand für diese Funktion sehr gering.

Beispiel #1 Beispiel-Informationen

Beispiel für den Formularaufbau des Upload-Fortschritts.

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

Die gespeicherten Daten in der Session sehen wie folgt aus:

    <?php
    $_SESSION["upload_progress_123"] = array(
     "start_time" => 1234567890,   // Anfragezeitpunkt
     "content_length" => 57343257, // POST-Gesamtdatenmenge (in Bytes)
     "bytes_processed" => 453489,  // Menge der empfangenen und verabreiteten Daten (in Bytes)
     "done" => false,              // true, wenn die POST-Datenverarbeitung beendet ist (erfolgreich oder nicht)
     "files" => array(
      0 => array(
       "field_name" => "file1",       // Name des <input/>-Feldes
       // Die nächsten drei Elemente entsprechen den Angaben in $_FILES
       "name" => "foo.avi",
       "tmp_name" => "/tmp/phpxxxxxx",
       "error" => 0,
       "done" => true,                // true, wenn die POST-Datenverarbeitung dieser Datei beendet ist
       "start_time" => 1234567890,    // Zeitpunkt, an dem die Verarbeitung der Datei begonnen hat
       "bytes_processed" => 57343250, // Anzahl der empfangenen und verarbeiteten Daten dieser Datei (in Bytes)
      ),
      // Eine weitere Datei, die noch nicht komplett hochgeladen ist, in derselben Anfrage
      1 => array(
       "field_name" => "file2",
       "name" => "bar.avi",
       "tmp_name" => NULL,
       "error" => 0,
       "done" => false,
       "start_time" => 1234567899,
       "bytes_processed" => 54554,
      ),
     )
    );

Warnung

Damit dies richtig funktioniert, muss die Anfragepufferung des Webservers deaktiviert sein, sonst sieht PHP den Datei-Upload möglicherweise erst, wenn er abgeschlossen ist. Server wie Nginx sind bekannt dafür, große Anfragen zu puffern.

Achtung

Die Upload-Fortschrittsinformationen werden in die Session geschrieben, bevor irgendein Skript ausgeführt wird. Daher führt die Änderung des Session-Namens per ini_set() oder session_name() zu einer Session ohne die Upload-Fortschrittsinformationen.

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open