Выход PHP с сна ()

Я пытаюсь запустить цикл каждую секунду в течение 25 секунд в основном.

for($i = 0; $i <= 25; $i += 1){ 
    echo $i;
    sleep(1)
}

Дело в том, что он не выводится до тех пор, пока не будет полностью завершен, поэтому цикл продолжается 25 раз. Есть ли способ сделать это, чтобы он выводил перед каждым сном? и не ждать, пока завершится полный цикл?

Спасибо!

3 ответа

То, что вы пытаетесь достичь, это инкрементальный вывод в браузер из PHP.

Достижимо ли это, зависит от вашего сервера и от того, как вы вызываете PHP.

PHP под FastCGI

Скорее всего, вы столкнетесь с подобной проблемой, когда PHP работает под FastCGI, а не как модуль Apache, потому что связь между сервером и процессами PHP не так тесно связана. Связь FastCGI использует буферизацию вывода после того, как данные вышли из процессов PHP, а вывод отправляется в браузер только после полного завершения запроса или заполнения этого буфера. Кроме того, процессы PHP, как правило, завершаются через определенное время, чтобы избежать слишком долгого запуска любого из них.

Тем не менее, сочетание ob_end_flush() (или же ob_flush()) а также flush() должен по-прежнему заставлять PHP запрашивать очистку нижестоящих буферов, так что это все еще может работать. Возможно, вам также понадобится выяснить, нужно ли вам увеличивать ограничение по времени для сценариев PHP.

PHP под mod_php

Если вы используете mod_php, вы можете постепенно записывать данные в браузер. Используйте команду flush(), чтобы гарантировать, что модуль PHP мгновенно сбросит его. Если у вас нет выходной буферизации или какого-либо модуля Apache, такого как mod_gzip, то он должен немедленно перейти в браузер пользователя. Более того, вы можете поддерживать ваш PHP-скрипт так долго, как вам нравится (с помощью set_time_limit() в PHP), в конфигурациях по умолчанию, хотя, конечно, он будет занимать немного памяти.

Вы можете столкнуться с проблемами в некоторых браузерах, которые не начинают отображать страницу до тех пор, пока не будет загружено определенное количество страниц. Некоторые версии IE могут ждать 1 КБ. Я обнаружил, что Chrome может ждать большего. Многие люди обходят это, добавляя отступы, такие как длинный комментарий длиной 1 или 2 КБ в верхней части документа.

Я только что решил эту проблему с точки зрения новичка и придумал этот простой сценарий, который будет делать то, что вы хотите.

<?PHP
ob_start();
$buffer = str_repeat(" ", 4096)."\r\n<span></span>\r\n";

for ($i=0; $i<25; $i++) {
  echo $buffer.$i;
  ob_flush();
  flush();
  sleep(1);
}

ob_end_flush();
?>

Вопросы, которые вы можете задать, могут быть здесь\r\n) и здесьob_flush()). Надеюсь, это поможет вам.

Вызов flush заставит PHP передать весь выходной буфер клиенту, прежде чем продолжить.

for($i = 0; $i <= 25; $i += 1){ 
    echo $i;
    flush();
    sleep(1);
}

РЕДАКТИРОВАТЬ:

После тестирования этого на моем сервере lighttpd я заметил, что он буферизовал мои выходные данные в блоках по 4096 символов, и я предполагаю, что другие браузеры могут иметь аналогичные схемы буферизации. Также GZIP может помешать flush полностью. К сожалению, нет способа проверить, что он работает из-за природы HTTP.

Еще одна проблема, связанная с этой стратегией, заключается в том, что PHP-процесс блокируется для других запросов. Это может привести к тому, что запросы будут накапливаться.

Другие вопросы по тегам