Привет. Сегодня речь пойдет о создании качественного отображения текущего состояния неких обработчиков. Допустим у нас есть скрипт, который выполняет какие-то длительные действия. 20-30 минут. И обычно у этой страницы отсутствует отклик. Колесико крутится, а что в данный момент происходит и сколько еще работы – неизвестно.
И проблема даже не в том, чтобы узнать весь объем данных. Мы можем заранее узнать число повторений, которых скрипту нужно отработать, но точно не можем узнать время каждого повторения.
Вывод echo текущее состояние частично решает проблему, но позволяет вывести информацию браузеру, как только заполнится некий буфер. Для вывода коротких логов – такое вывести затруднительно. И то это работает только для браузеров Firefoxи Internet Explorer. И ведь с точки зрения логики – реализация накопительного буфера является более быстрой с точки зрения скрипта и стандартных веб-страниц, время открытия которых не должно превышать секунду.
С появлением технологии Ajax– скрипт может оставлять заметки, например в локальный файл, а мы на странице его запустившей – считывать общий прогресс с периодичностью в секунду-две. Но это скорее сложный путь. Это также путь не универсальный, т.к. одновременно может быть запущен только 1 скрипт.
Разгадка простого метода кроется в спасательной для нас функции
ob_implicit_flush(true);
После нее – выполнение любого вывода echo– будет выведено мгновенно.
Но это только первая часть статьи. Далее – давайте наведем красоту. В сети можно найти множество красивых прогресс-баров. Суть кроется в том, что при каждом выводе echo– программа выведет и отработает ту часть скрипта, которая в ней описана. А если ранее содержался скрипт со ссылкой src– он также будет получен вне очереди
Нижеприведенный скрипт хорошо демонстрирует все эти возможности
<script src="jquery.js"></script>
<script>var time=Math.round(new Date().getTime()/100)</script>
<div id="progressbar"></div>
<?php
ob_implicit_flush(true);
for ($i=0;$i<100;$i++){
?><script>var newtime=Math.round(new Date().getTime()/100)-time;$("#progressbar").html(newtime);console.log(newtime);</script><?
usleep(100000);
}
Теперь можно объединить все это, например с css-tricks.com/css3-progress-bars/
Наше счастье было бы полным, если бы такое всегда работало, но как показывает практика – с апачем на Linuxтакое не всегда прокатывает. Для этого – мы можем принудительно переполнить буфер, выбив толщи пустых строк, например следующим образом
$text=str_repeat('<!--1-->',1500);
Для примера с Progressbar от css-tricks – рабочий пример может быть выглядеть следующим образом
<script src="jquery.js"></script>
<link rel="stylesheet" href="progressbar.css">
<div class="meter orange nostripes">
<span id="progressbar"></span>
</div>
<script>var progress=$('#progressbar');</script>
<?php
$empty=str_repeat('<!--1-->',1500);
$total=100; // определяем общее число повторений
foreach ($array as $key=>$data){
…
?>
<script>progres.css('width','<?=round($key/$total*100)?>%' )</script>
<?
echo $empty;
@ob_flush();
}
Если хотите – можно даже избавиться от Jquery, т.к. надобности в нем большой нету
Удачи в создании дружелюбного и отзывчивого веба