セッションのアップロード状況
注意:
この機能は、PHP 5.4.0 以降で利用可能です。
INI オプション session.upload_progress.enabled を有効にすると、アップロード中の個々のファイルの進捗状況を PHP で追えるようになります。 この情報は、アップロードのリクエスト自体にとっては特に有用ではありませんが、 ファイルのアップロード中にアプリケーションから別のエンドポイントに POST リクエストを (XHR などで) 送って状態をチェックできるようになります。
アップロードの状況は、アップロードの処理中にスーパーグローバル $_SESSION
で取得できます。また、 INI オプション
session.upload_progress.name
で設定した名前でも POST されます。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() 関数で変更してしまうと、 アップロード状況の情報が欠落したセッションが提供されることになります。