- Отслеживание прогресса загрузки файлов с помощью сессий
- Php+Ajax полоса загрузки ProgressBar
- Пишем PHP скрипт для полосы загрузки с использованием AJAX
- AJAX обработчик (Шаг 1)
- Пишем скрипт PHP выполняющий «сложную задачу» (Шаг 2)
- Организация процесса обновления полосы загрузки и вывод её на страницу (3 шаг)
- Читайте также похожие статьи:
- Показатель обратной загрузки файла для форм (Upload Progress Meter)
Отслеживание прогресса загрузки файлов с помощью сессий
PHP может отслеживать прогресс загрузки отдельных файлов при включённой опции session.upload_progress.enabled. Данная информация не особенно полезна для запроса, непосредственно закачивающего файл, однако, в течение данной загрузки приложение может посылать POST-запросы на отдельную страницу (например, с помощью XHR ) для проверки статуса.
Прогресс закачки будет доступен в суперглобальной переменной $_SESSION во время выполнения загрузки, а также при отправке POST-запросом переменной с именем, равным значению опции session.upload_progress.name. Как только PHP обнаружит такой POST-запрос, он создаст массив в $_SESSION , ключом которого будет конкатенация значений опций session.upload_progress.prefix и session.upload_progress.name. Ключ обычно можно получить прочитав эти опции, то есть:
$key = ini_get ( «session.upload_progress.prefix» ) . $_POST [ ini_get ( «session.upload_progress.name» )];
var_dump ( $_SESSION [ $key ]);
?>?php
Также возможно отменить загружаемый в данный момент файл, установив ключ $_SESSION[$key][«cancel_upload»] в значение true . При загрузке нескольких файлов за один раз, это действие отменит только текущий загружаемый файл и все следующие за ним, но не удалит уже успешно загруженные к этому времени файлы. Если закачка была отменена этим способом, то элемент с ключом error в массиве $_FILES будет установлен в UPLOAD_ERR_EXTENSION .
Опции session.upload_progress.freq и session.upload_progress.min_freq контролируют частоту обновления информации о прогрессе загрузки. При разумных значениях этих двух настроек, накладные расходы данной функции практически неощутимы.
Пример #1 Пример
Пример структуры массива прогресса загрузки.
Данные в сессии будут выглядеть примерно так:
$_SESSION [ «upload_progress_123» ] = array(
«start_time» => 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
Для успешной работы данной функции необходимо отключить буферизацию запроса веб-сервером. Иначе PHP увидит загрузку файла только когда загрузка полностью завершится. Серверы, такие как например Nginx, буферизуют большие запросы.
Информация о прогрессе загрузки записывается в сессию до того, как будет запущен какой либо скрипт. Поэтому изменение имени сессии с помощью ini_set() или session_name() выдаст сессию без информации о прогрессе загрузки.
Php+Ajax полоса загрузки ProgressBar
Здравствуй уважаемый читатель блога LifeExample, ты знаешь, что такое ProgressBar? ProgressBar — это индикатор, который показывает скорость и процент выполнения любого процесса. ProgressBar также называют полосой загрузки, или индикатором загрузки. Обычно прогресс бар используют для отображения процесса скачивания или закачивания файлов, но существуют и другие способы применения. Почему то в интернете все ссылки связанные использованием ProgressBar на php, сводятся к загрузке файлов, неужели людям не нужно отслеживать процесс выполнения других задач? Например, таких как процент считывания XML файла, или процесс заполнения SQL таблицы данными. Немало важным индикатор отслеживания является и при работе с удаленным сервером.
Недавно мне пришлось разработать грабер для одной фирмы. Грабер должен был: получить с сайта конкурентов, каталог продукции, сохранив структуру вложенности разделов. Так вот при частом обращении с чужому серверу, с целью получения кода страницы, для дальнейшего парсинга, уходит много времени, что влечет за собой появление ошибки выполнения сценария:
Fatal error: Maximum execution time of 30 seconds exceeded in …
Для того чтобы избежать данной оказии, нужно разбить наш процесс на части, таким образом чтобы каждая из частей при выполнении укладывалась в 30 секундный интервал. В этот момент как раз таки и неплохо знать, сколько же процентов выполнилось, и сколько еще осталось ждать.
Пишем PHP скрипт для полосы загрузки с использованием AJAX
Представим, что у нас есть объемный алгоритм, который обрабатывает информацию по частям, и назовем его условно «сложной задачей». Чтобы было понятно, представьте что информацией является разбитый на части файл, который нужно скачать с сервера.
Создавать ProgressBar мы будем последовательно, выполнив для этого 3 шага.
AJAX обработчик (Шаг 1)
Сразу скажу, что для корректной работы AJAX технологии нам понадобится, уже готовый скрипт: ajax.js , в задачи которого входит отправка запросов на сервер и ожидание ответа. На самом деле он не большой, и можно было бы описать его более подробно, но боюсь, что это сделает статью слишком длинной. О работе с AJAX я напишу подробнее в другой статье, а пока просто выложу код упомянутого выше скрипта:
function XmlHttp ( )
{
var xmlhttp ;
try { xmlhttp = new ActiveXObject ( «Msxml2.XMLHTTP» ) ; }
catch ( e )
{
try { xmlhttp = new ActiveXObject ( «Microsoft.XMLHTTP» ) ; }
catch ( E ) { xmlhttp = false ; }
}
if ( ! xmlhttp && typeof XMLHttpRequest != ‘undefined’ )
{
xmlhttp = new XMLHttpRequest ( ) ;
}
return xmlhttp ;
}
function ajax ( param )
{
if ( window. XMLHttpRequest ) req = new XmlHttp ( ) ;
send = «» ;
for ( var i in param. data ) send += i + «=» + param. data [ i ] + «&» ;
req. open ( «POST» , param. url , true ) ;
req. setRequestHeader ( «Content-Type» , «application/x-www-form-urlencoded» ) ;
req. send ( send ) ;
req. onreadystatechange = function ( )
{
if ( req. readyState == 4 && req. status == 200 ) //если ответ положительный
{
if ( param. success ) param. success ( req. responseText ) ;
}
}
}
И так, скачайте данный скрипт, и положите его в корневую папку вашего сайта, либо в ручную создайте пустой файл ajax.js и вставьте в него приведенный выше код.
Пишем скрипт PHP выполняющий «сложную задачу» (Шаг 2)
Вторым действием создадим скрипт index.php , который будет отвечать за вывод полосы загрузки на страницу, а также будет выполнять расчет «сложной задачи». В корневой папке сайта создайте пустой файл index.phр. Откройте его и вставьте следующий код:
session_start ( ) ; //открываем сессию для записи
if ( $_POST [ «difficult_task» ] ) {
$part = 231 ; //общее количество задач
$_SESSION [ ‘sucsess_part’ ] ++; //количество выполненных подзадач
echo floor ( ( $_SESSION [ ‘sucsess_part’ ] * 100 ) / $part ) ; //процент выполненния общей задачи
}
?>
else
…
Эта часть кода описывает процесс выполнения «сложной задачи», если интерпретировать ее на задачу скачивания файла, то переменная $part должна содержать количество частей разбитого файла. Счетчик уже скачанных частей должен храниться в сессии на сервере, поэтому сразу открываем ее для записи функцией session_start(), для того чтобы в дальнейшем увеличивать $_SESSION[‘sucsess_part’] на один, каждый раз при успешной закачке одной из частей файла. Функция floor() округляет выполненные проценты скачивания до целого числа в меньшую сторону.
Вот и весь скрипт расчета сложной задачи, конечно на практике данный скрипт разрастётся сотнями строк, но для общего примера хватит и данного кода. В принципе правильнее было бы выделить этот скрипт отдельно и обращаться к нему с html странички с помощью ajax.js, но т.к. он слишком мал, то будет понятнее включить обработчик «сложной задачи» непосредственно в код страницы.
Организация процесса обновления полосы загрузки и вывод её на страницу (3 шаг)
Код вывода HTML страницы и progressbar будет заключен между скобками else из предыдущего шага:
Скопируйте следующий кусок кода и вставьте его вместо многоточия.
Данный код выводит на страницу кнопку с названием ‘Выполнить сложную задачу’, при нажатии на которую запускается процесс обработки сложной задачи с использованием ajax запросов. В коде присутствуют комментарии, поэтому не стану их дублировать, просто советую внимательно посмотреть что там написанно.
Если вы все сделали правильно, то у вас в корне сайта должны лежать два файла: index.php и ajax.js, в противном случаем вы можете скачать их одним архивом.
Запустите index.php вы увидите кнопку ‘Выполнить сложную задачу’. Нажмите на нее, и синяя полоса загрузки начнет заполняться зеленым цветом.
При достижении 100% вы увидите сообщение о успешном выполнении «сложной задачи».
Помните о том, что счетчик выполнения хранится в сессии на стороне сервера, поэтому для того, чтобы вновь посмотреть работу скрипта вам нужно будет перезапустить браузер, либо дописать скрипт самостоятельно таким образом, чтобы сессия сбрасывалась при достижении 100% результата.
Сегодня в статье с ужасным названием php+ajax полоса загрузки progressbar
мы рассмотрели, очень полезный на мой взгляд, механизм отслеживания выполнения задачи в процентах с выводом графического индикатора. Полоса загрузки, или попросту progressbar, будет полезен при синхронизации данных, при скачивании или закачивании файлов, а также при удаленной работе с чужим сайтом.
Читайте также похожие статьи:
Чтобы не пропустить публикацию следующей статьи подписывайтесь на рассылку по E-mail или RSS ленту блога.
Показатель обратной загрузки файла для форм (Upload Progress Meter)
Они служат для показания процента аплоада на сервер файла который вы заливаете через форму. К сожалению, на самом простом уровне показать процент аплоада нельзя, а хотелось бы. Согласитесь видеть процент загрузки всегда приятней чем скучный «Loading. » в строке-статуса браузера, поэтому я расскажу как сделать такой аплоад-показатель для ваших форм загрузок.
Чтобы еще лучше понять о чем речь попробуйте рабочий пример:
php5.bluga.net/UploadProgressMeter/demo.php
Для начала я установил новенький http сервер Apache версия 2.2.4 и не совсем новенький PHP 5.2.0
Надеюсь устанавливать эти приложения вы умете, я скажу лишь что делал это под Windows поэтому к php нам нужно будет подключить два расширения .dll если они еще у вас не установлены, это:
php_apc.dll
php_json.dll
Чтобы установить эти расширения нужно положить эти файлы папку расширений вашего сервера, чтобы узнать что это за папка выполните phpinfo(); и посмотрите переменную extension_dir (обычно C:\php\ext)
В php.ini подключите их:
extension=php_apc.dll
extension=php_json.dll
Также следует задать параметры для php_apc, также в php.ini:
extension=php_apc.dll
apc.shm_segments=1
apc.optimization=0
apc.shm_size=128
apc.ttl=7200
apc.user_ttl=7200
apc.num_files_hint=1024
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.enable_cli=1
apc.rfc1867=On
Обратите внимание на последнюю установку, а именно apc.rfc1867 она непосредственно относиться к нашей задаче. больше по настройкам APC тут.
Установите php_apc если запустите лежащий внутри папки файл получите такую картинку:
Проверьте загрузились ли модули, это можно сделать функцией extension_loaded
Теперь создайте файл php и вставте в него такой текст такой текст всё должно работать, в нём используется библиотека пользовательского интерфеса Yahoo! для создания двигающейся полосы загрузки, вы можете использовать что-то своё.
Возможно вам прийдется удаленно работать с сервером:
www.odessa.net/docs/LINUX/SHELL/shell.html
Сейчас есть uploadprogressextension для таких целей, это конечно тоже вариант но не люблю лишними екстеншинами загружать сервер, а php_apc и php_json всётаки и так бы стояли.
Спасибо за внимание.