У меня возникают проблемы с очисткой буфера вывода PHP на моем веб-сервере Linux. Буфер вывода поддерживается правильно, и все нужные данные помещаются в него в моем коде, но обычные механизмы очистки не сбрасывают его в браузер. Я пробовал все, что написано здесь: http://php.net/manual/en/function.flush.php но пока безуспешно.
Я получил небольшой скрипт с php.net для проверки:
<?php
ob_start();
for($i=0;$i<70;$i++)
{
echo 'printing...<br />';
ob_get_flush();
flush();
usleep(300000);
}
?>
Это должно напечатать "печать ..." в браузере 70 раз, по одной строке каждые три секунды. Это отлично работает в другой моей тестовой среде, основанной на Windows (все еще использующей apache, пакет XAMPP), но на моем сервере Linux это не так. Он ожидает завершения сценария, прежде чем передать что-либо браузеру, в основном игнорируя всю команду flush.
Если кто-то сталкивался с этим раньше или знает что-нибудь, что могло бы помочь (будь то конфигурация сервера или корректировка кода), мы будем очень признательны!
У меня была эта проблема, и я обнаружил, что строки:
while ( @ob_end_flush() ); // even if there is no nested output buffer
flush();
решит проблему.
Результаты могут отличаться. Это работает в моей системе с IE и Apache 2.0.55.
Джефф
Как отмечено в документации PHP, по моему опыту, распространенной причиной этого является буферизация вывода с помощью mod_gzip на Apache. Во многих дистрибутивах эта функция включена по умолчанию.
отметка
Очистка буфера вывода PHP и очистка буфера Apache - это две разные задачи. Часто бывает, что вы очищаете выходной буфер PHP, но Apache ничего не отправляет в браузер, пока не будет больше данных. Кроме того, иногда браузер ничего не отображает, пока не получит достаточно данных. Что вы можете попробовать, так это «дополнить» свой вывод символами новой строки.
Есть еще две проблемы с опубликованным вами кодом. Сначала он запускает буферизацию вывода один раз, а затем завершает ее несколько раз в цикле. Вы либо хотите, чтобы буферизация вывода также была внутри цикла, либо можете просто опустить ее. Другой вопрос, ob_get_flush()
вернет содержимое выходного буфера в виде строки, а не эхом.
Вместо этого попробуйте этот код:
<?php
for($i=0;$i<70;$i++)
{
echo 'printing...<br />';
echo str_repeat("\n",1024);
flush();
usleep(300000);
}
?>
Из Руководства по PHP:
flush () может быть не в состоянии переопределить схему буферизации вашего веб-сервера и не влияет на буферизацию на стороне клиента в браузере. [...]
Серверные модули для Apache, такие как mod_gzip, могут выполнять буферизацию самостоятельно, что приведет к тому, что flush () не приведет к немедленной отправке данных клиенту.
Даже браузер может буферизовать свой ввод перед его отображением. Netscape, например, буферизует текст до тех пор, пока не получит конец строки или начало тега, и не будет отображать таблицы, пока не будет виден тег самой внешней таблицы.
Некоторые версии Microsoft Internet Explorer начнут отображать страницу только после того, как получат 256 байтов вывода, поэтому вам может потребоваться отправить дополнительные пробелы перед очисткой, чтобы эти браузеры отображали страницу.
Мой пример пытается обойти это, отправляя 1024 символа новой строки.