# セッションのアップロード状況

INI オプション session.upload_progress.enabled を有効にすると、アップロード中の個々のファイルの進捗状況を PHP で追えるようになります。 この情報は、アップロードのリクエスト自体にとっては特に有用ではありませんが、 ファイルのアップロード中にアプリケーションから別のエンドポイントに POST リクエストを (XHR などで) 送って状態をチェックできるようになります。

アップロードが進行中かつ、INI オプション session.upload_progress.name に設定されているのと同じ名前の変数が POST されていると、アップロードの状況を スーパーグローバル $_SESSION から取得できます。 PHP 側では、この POST リクエストを検出すると $_SESSION 内の配列に値を格納します。配列のインデックスは、INI オプション session.upload_progress.prefix と session.upload_progress.name の値をつなげたものです。つまり、これらの INI 設定を読んで次のようにキーを取得することになります。

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

現在進行中のファイルアップロードをキャンセルすることもできます。 キャンセルするには、`$_SESSION[$key]["cancel_upload"]` に `true` を設定します。複数のファイルをひとつのリクエストでアップロードしている場合は、 これでキャンセルできるのは現在進行中のアップロードとそれ以降にアップロードする予定だったファイルだけです。 既にアップロードが完了したファイルは削除されません。この方法でアップロードをキャンセルした場合、 $_FILES 配列のキー `error` に `UPLOAD_ERR_EXTENSION` が設定されます。

INI オプション session.upload_progress.freq および session.upload_progress.min_freq で、アップロードの進捗状況を再計算する頻度を制御します。 これらを適切に設定すれば、進捗状況の取得によるオーバーヘッドはほぼ無視できる程度になります。

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

セッションに格納されるデータは、このようになります。

    <?php
    $_SESSION["upload_progress_123"] = array(
     "start_time" => 1234567890,   // リクエストされた時刻
     "content_length" => 57343257, // POST されたコンテンツの長さ
     "bytes_processed" => 453489,  // 受信して処理済みのバイト数
     "done" => false,              // POST ハンドラが (正常かどうかにかかわらず) 完了した場合に true
     "files" => array(
      0 => array(
       "field_name" => "file1",       // <input/> フィールドの name
       // 次の 3 つの要素は $_FILES と同じ内容です
       "name" => "foo.avi",
       "tmp_name" => "/tmp/phpxxxxxx",
       "error" => 0,
       "done" => true,                // POST ハンドラがこのファイルの処理を終えたときに true
       "start_time" => 1234567890,    // このファイルの処理が始まった時刻
       "bytes_processed" => 57343250, // このファイルにおける、受信して処理済みのバイト数
      ),
      // 同じリクエスト内で、まだアップロードが完了していない別のファイル
      1 => array(
       "field_name" => "file2",
       "name" => "bar.avi",
       "tmp_name" => NULL,
       "error" => 0,
       "done" => false,
       "start_time" => 1234567899,
       "bytes_processed" => 54554,
      ),
     )
    );

警告

ウェブサーバーのリクエストバッファリングを無効にしておかないと、うまく動作しません。 リクエストバッファリングが有効になっていると、PHP 側ではアップロードが完全に終わるまでアップロードされたことがわかりません。 たとえば Nginx などのサーバーは、大きなリクエストをバッファリングするようになっています。

警告

アップロード状況の情報は、あらゆるスクリプトを実行する前に、セッションに書き込まれます。 よって、セッション名を ini_set() 関数や session_name() 関数で変更してしまうと、 アップロード状況の情報が欠落したセッションが提供されることになります。

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