Отслеживание хода загрузки файлов через сессии
PHP Manual
PHP Manual»Сессии»Отслеживание хода загрузки файлов через сессии

Отслеживание хода загрузки файлов через сессии

PHP умеет отслеживать ход загрузки отдельных файлов, если включить INI-директиву session.upload_progress.enabled. Эта информация не приносит пользы самому запросу на отправку файла, но во время загрузки файла приложение может отправить POST-запрос отдельной конечной точке, например через интерфейс XHR, чтобы проверить статус.

Ход загрузки будет доступен в суперглобальной переменной $_SESSION по мере загрузки файла, и при отправке POST-переменной с тем же именем, которое установили для INI-параметра session.upload_progress.name. Когда PHP обнаруживает такие POST-запросы, он заполняет в переменной $_SESSION массив, в котором ключом будет конкатенация значений опций session.upload_progress.prefix и session.upload_progress.name. Ключ обычно получают путём чтения значений этих директив, то есть:

<?php

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

?>

Разработчики отменяют текущую загрузку файла через установку для ключа $_SESSION[$key]["cancel_upload"] значения true, когда требуется. При загрузке набора файлов в одном запросе этот способ отменит только текущую загрузку файла, которая уже началась, и загрузки в очереди, но не удалит загрузки, которые уже завершились. При отмене загрузки таким способом PHP установит элементу массива $_FILES с ключом error значение константы UPLOAD_ERR_EXTENSION.

Директивы 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",       // Значение атрибута name поля <input/>
            // Следующие 3 элемента соответствуют элементам суперглобального массива $_FILES
            "name" => "foo.avi",
            "tmp_name" => "/tmp/phpxxxxxx",
            "error" => 0,
            "done" => true,                // Элемент получает значение true, когда обработчик POST-запроса
                                           // закончил обработку файла
            "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 буферизуют большие запросы.

Предостережение

Информация о ходе загрузки записывается в сессию перед выполнением скриптов. Поэтому PHP начнёт сессию без информации о ходе загрузки, если изменить название сессии функцией ini_set() или session_name().

To Top