Отслеживание прогресса загрузки файлов с помощью сессий
PHP может отслеживать прогресс загрузки отдельных файлов при
включённой опции
session.upload_progress.enabled.
Данная информация не особенно полезна для запроса, непосредственно
закачивающего файл, однако, в течение данной загрузки приложение
может посылать POST-запросы на отдельную страницу (например,
с помощью XHR) для проверки статуса.
Прогресс закачки будет доступен в суперглобальной переменной
$_SESSION во время выполнения загрузки, а также при
отправке POST-запросом переменной с именем, равным значению опции
session.upload_progress.name.
Как только PHP обнаружит такой POST-запрос, он создаст массив
в $_SESSION, ключом которого будет конкатенация
значений опций
session.upload_progress.prefix
и
session.upload_progress.name.
Ключ обычно можно получить прочитав эти опции, то есть:
]]>
Также возможно отменить загружаемый в данный момент файл,
установив ключ $_SESSION[$key]["cancel_upload"] в значение &true;.
При загрузке нескольких файлов за один раз, это действие отменит
только текущий загружаемый файл и все следующие за ним, но не удалит
уже успешно загруженные к этому времени файлы.
Если закачка была отменена этим способом, то элемент с ключом
error в массиве $_FILES
будет установлен в UPLOAD_ERR_EXTENSION.
Опции session.upload_progress.freq
и session.upload_progress.min_freq
контролируют частоту обновления информации о прогрессе загрузки.
При разумных значениях этих двух настроек, накладные расходы данной
функции практически неощутимы.
Пример
Пример структуры массива прогресса загрузки.
" value="123" />
]]>
Данные в сессии будут выглядеть примерно так:
1234567890, // Время начала запроса
"content_length" => 57343257, // Длина содержимого POST
"bytes_processed" => 453489, // Количество полученных и обработанных байт
"done" => false, // true при завершении обработки POST, успешно или нет
"files" => array(
0 => array(
"field_name" => "file1", // Имя поля
// Следующие 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, буферизуют большие запросы.
Информация о прогрессе загрузки записывается в сессию до того, как будет
запущен какой либо скрипт. Поэтому изменение имени сессии с помощью
ini_set или session_name выдаст
сессию без информации о прогрессе загрузки.