Как очистить выходные данные после каждого вызова echo?

У меня есть php-скрипт, который только производит журналы для клиента.
Когда я что-то повторяю, я хочу, чтобы он был передан клиенту «на лету».
(Поскольку во время обработки скрипта страница пуста)
Я уже играл с ob_start() и ob_flush() , но они не работали.

Какое лучшее решение?

PS: немного грязно положить флеш в конце echo звонка …

EDIT: Ни ответы не работали, ни PHP, ни Apache Fault?

Редактировать:

Я читал комманды на странице руководства и наткнулся на ошибку, в которой указано, что ob_implicit_flush не работает, и ob_implicit_flush является следующее:

 ob_end_flush(); # CODE THAT NEEDS IMMEDIATE FLUSHING ob_start(); 

Что может даже произойти, так это то, что клиент не получает пакет с сервера, пока сервер не создаст достаточно символов для отправки того, что он считает отправкой пакета.


Старый ответ:

Вы можете использовать ob_implicit_flush который будет ob_implicit_flush буферизацию вывода, чтобы отключить буферизацию на некоторое время:

 ob_implicit_flush(true); # CODE THAT NEEDS IMMEDIATE FLUSHING ob_implicit_flush(false); 

Я получил ту же проблему, и один из опубликованных примеров в руководстве работал. Набор символов должен быть указан как один из плакатов, о которых уже упоминалось. http://www.php.net/manual/en/function.ob-flush.php#109314

 header( 'Content-type: text/html; charset=utf-8' ); echo 'Begin ...<br />'; for( $i = 0 ; $i < 10 ; $i++ ) { echo $i . '<br />'; flush(); ob_flush(); sleep(1); } echo 'End ...<br />'; 

Итак, вот что я узнал.

Флеш не работал бы с помощью apache mod_gzip или gzip от Nginx, потому что, по логике, это gzipping содержимое, и для этого он должен буферизовать контент, чтобы его gzip. Любой вид gzipping веб-сервера повлияет на это. Короче говоря, на стороне сервера нам нужно отключить gzip и уменьшить размер буфера fastcgi. Так:

  • В php.ini:

     output_buffering = Off zlib.output_compression = Off 
  • В nginx.conf:

     gzip off; proxy_buffering off; 

Также имейте эти строки под рукой, особенно если у вас нет доступа к php.ini:

 @ini_set('zlib.output_compression',0); @ini_set('implicit_flush',1); @ob_end_clean(); set_time_limit(0); 

Наконец, если у вас есть это, прокомментируйте приведенный ниже код:

 ob_start('ob_gzhandler'); ob_flush(); 

Код проверки PHP:

 ob_implicit_flush(1); for ($i=0; $i<10; $i++) { echo $i; // this is to make the buffer achieve the minimum size in order to flush data echo str_repeat(' ',1024*64); sleep(1); } 

Попытка, по-видимому, не работающая, является побочным эффектом автоматического обнаружения набора символов.

Браузер ничего не отобразит, пока не узнает набор символов для его отображения, и если вы не укажете набор символов, ему нужно попытаться угадать его. Проблема заключается в том, что он не может сделать хорошее предположение без достаточного количества данных, поэтому браузеры, похоже, имеют этот 1024-байтовый (или подобный) буфер, который им нужно заполнить перед отображением чего-либо.

Поэтому решение состоит в том, чтобы убедиться, что браузеру не нужно угадывать набор символов.

Если вы отправляете текст, добавьте '; charset = utf-8 'для своего типа содержимого, а если это HTML, добавьте набор символов в соответствующий метатег.

то, что вы хотите, это метод флеша . пример:

 echo "log to client"; flush(); 

Почему бы не сделать функцию для эха, например:

 function fecho($string) { echo $string; ob_flush(); } 

Правильная функция для использования – flush() .

 <html> <body> <p> Hello! I am waiting for the next message...<br /> <?php flush(); sleep(5); ?> I am the next message!<br /> <?php flush(); sleep(5); ?> And I am the last message. Good bye. </p> </body> </html> 

Обратите внимание, что с IE существует «проблема», которая выводит только очищенный контент, когда он составляет не менее 256 байт, поэтому ваша первая часть страницы должна быть не менее 256 байт.

У меня было похожее дело. С помощью

 // ini_set("output_buffering", 0); // off ini_set("zlib.output_compression", 0); // off ini_set("implicit_flush", 1); // on 

действительно делал промывку вывода частой в моем случае.

Но мне нужно было очистить выход прямо в определенной точке (в цикле, который я запускаю), поэтому используя оба

 ob_flush(); flush(); 

вместе работали для меня.

Мне не удалось отключить «output_buffering» с помощью ini_set (…), пришлось повернуть его прямо в php.ini, phpinfo () показывает, что его значение «нет значения» при выключении, это нормально? ,

Попробуй это:

 while (@ob_end_flush()); ob_implicit_flush(true); echo "first line visible to the browser"; echo "<br />"; sleep(5); echo "second line visible to the browser after 5 secs"; 

Просто обратите внимание, что таким образом вы фактически отключите выходной буфер для вашего текущего скрипта. Я думаю, вы можете повторно использовать его с ob_start () (я не уверен).

Важно то, что, отключив выходной буфер, как описано выше, вы больше не сможете перенаправлять свой php-скрипт с помощью функции header() , поскольку php может отправляться только один раз для заголовков HTTP-скриптов. Однако вы можете перенаправить с помощью javascript. Просто позвольте вашему сценарию php эхом следовать строкам, когда дело доходит до этого:

  echo '<script type="text/javascript">'; echo 'window.location.href="'.$url.'";'; echo '</script>'; echo '<noscript>'; echo '<meta http-equiv="refresh" content="0;url='.$url.'" />'; echo '</noscript>'; exit; 

Антивирусное программное обеспечение также может мешать промывке продукта. В моем случае Антивирус Касперского 2013 года хранил куски данных перед отправкой в ​​браузер, хотя я использовал принятое решение.

Иногда проблема возникает из настроек Apache. Apache может быть настроен на gzip вывод. В файле .htaccess вы можете добавить, например:

 SetEnv no-gzip 1 

Обратите внимание, что если вы находитесь на определенных общедоступных сайтах хостинга, таких как Dreamhost, вы не можете отключить буферизацию вывода PHP вообще, не пройдя разные маршруты:

Изменение кеша выходного буфера Если вы используете PHP FastCGI, функции PHP flush (), ob_flush () и ob_implicit_flush () не будут функционировать должным образом. По умолчанию вывод буферизуется на более высоком уровне, чем PHP (в частности, модулем Apache mod_deflate, который похож по форме / функции на mod_gzip).

Если вам нужен небуферизованный вывод, вы должны либо использовать CGI (вместо FastCGI), либо обратиться в службу поддержки, чтобы запросить, чтобы mod_deflate был отключен для вашего сайта.

https://help.dreamhost.com/hc/en-us/articles/214202188-PHP-overview

Я опаздываю на обсуждение, но я читал, что многие люди говорят, что добавляет flush (); в конце каждого кода выглядит грязным, и они правы.

Лучшее решение – отключить deblate, gzip и всю буферизацию от Apache, промежуточных обработчиков и PHP. Затем в вашем php.ini вы должны:

  output_buffering = Off zlib.output_compression = Off implicit_flush = Off 

Временное решение заключается в том, чтобы иметь это в php.ini, если вы можете решить свою проблему с помощью flush (); но вы думаете, что это грязно и уродливо, чтобы его повсюду.

 implicit_flush = On 

Если вы только указали это в своем php.ini, вам не нужно ставить flush (); в вашем коде больше.

Это мой код: (работа для PHP7)

 private function closeConnection() { @apache_setenv('no-gzip', 1); @ini_set('zlib.output_compression', 0); @ini_set('implicit_flush', 1); ignore_user_abort(true); set_time_limit(0); ob_start(); // do initial processing here echo json_encode(['ans' => true]); header('Connection: close'); header('Content-Length: ' . ob_get_length()); ob_end_flush(); ob_flush(); flush(); }