Индикация процесса длительной обработки на PHP для ленивых :)
Иногда в веб-приложениях возникает необходимость выполнить какую-то обработку, занимающую больше нескольких секунд. В случае, если отображать процесс выполнения для пользователя нет необходимости можно обойтись скриптами, запускаемыми из командной строки (для PHP) или консольными утилитами (для ASP.NET).
Для отображения же процесса выполнения какой-то полезной работы (например, разбора и импорта большого XML-файла в БД) можно применить код на клиентской стороне, регулярно опрашивающий AJAX-запросом серверную часть. Сам процесс выполнение часть может быть реализована по разному. Начиная от отдельного thread'a (для ASP.NET) и заканчивая очередями заданий.
Самое быстрое решение для PHP, не требущее AJAX'a подсмотрено в Sypex Dumper Lite 1.0.8. Идея состоит в том, чтобы увеличить максимальное время выполнение скрипта с помощью set_time_limit() и выключить буферизацию вывода. Дополнительные заголовки применяются для отключения кеширования на клиенте:
// Заголовки для отключения кеширования в браузере
header("Expires: Tue, 1 Jul 2003 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Pragma: no-cache");
// Увеличиваем максимальное время выполнение скрипта
set_time_limit(6000);
// Весь вывод сразу будет отсылаться в браузер
ob_implicit_flush();
for ($i = 0; $i < 60; $i++)
{
echo '. ';
sleep(1);
}
В оригинальной реализации подобным образом выводятся небольшие фрагменты JavaScript-кода, добавляющие сообщения в определённую область на экране.
К недостаткам решения можно отнести:
- В случае, если включен safe mode в PHP,
set_time_limit()не сработает - Если перед apache стоит nginx или клиент находится за прокси, страница может быть показана пользователю только после полной загрузки
Идея чем-то похожа на технику Hidden IFrame для Comet.
