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

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

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

PS: Это немного грязно, чтобы поставить флеш в конце echo звонок...

EDIT: ни ответы не работали, PHP или Ошибка Apache?

16 ответов


Edit:

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

ob_end_flush();

# CODE THAT NEEDS IMMEDIATE FLUSHING

ob_start();

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


старый Ответ:

вы могли бы использовать 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 />';

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

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

  • в php.ini:

    output_buffering = Off
    
    zlib.output_compression = Off
    
  • In 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();
}

для тех, кто придет в 2018 году:

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

<?php

    if (ob_get_level() == 0) ob_start();
    for ($i = 0; $i<10; $i++){

        echo "<br> Line to show.";
        echo str_pad('',4096)."\n";    

        ob_flush();
        flush();
        sleep(2);
    }

    echo "Done.";

    ob_end_flush();
?>

и очень важно сохранить часть de "4096", потому что кажется, что" заполняет " буфер...


у меня было аналогичное дело. Используя

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

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

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

ob_flush();
flush();

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

Я не смог выключите "output_buffering" С безопасность(...), пришлось повернуть его напрямую в PHP.ini, phpinfo () показывает его настройку как "нет значения" при включении выкл, что нормально? .


правильные функции 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 байтов.


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


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

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-скрипт с помощью


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

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

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

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


Это мой код: (работа для 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();
}

это отлично работает для меня (Apache 2.4 / PHP 7.0):

@ob_end_clean();
echo "lorem ipsum...";
flush();
sleep(5);
echo "<br>dolor...";
flush();
sleep(5);
echo "<br>sit amet";

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

SetEnv no-gzip 1

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

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

            output_buffering = Off
            zlib.output_compression = Off
            implicit_flush = Off

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

implicit_flush = On

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