Подтвердить что ты не робот

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

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

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

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

РЕДАКТИРОВАТЬ: Ни работали ответы, ни PHP, ни Apache Fault?

4b9b3361

Ответ 1

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);

Ответ 2

Я получил ту же проблему, и один из опубликованных примеров в руководстве работал. Набор символов должен быть указан как один из плакатов, о которых уже упоминалось. 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 />';

Ответ 3

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

Флеш не будет работать под Apache mod_gzip или Nginx gzip, потому что он логически является 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);
}

Ответ 4

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

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

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

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

Ответ 5

то, что вы хотите, это метод flush. Пример:

echo "log to client";
 flush();

Ответ 6

Для тех, кто приезжает в 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();
?>

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

Ответ 7

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

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

Ответ 8

У меня было похожее дело. Использование

// 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() показывает настройку как "нет значения" при выключении, это нормальный?.

Ответ 9

Правильная функция для использования - 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 байт.

Ответ 10

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

Ответ 11

Это прекрасно работает для меня (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";

Ответ 12

Попробуйте следующее:

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";

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

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

        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;

Ответ 13

Обратите внимание, что если вы находитесь на определенных общедоступных сайтах хостинга, таких как 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

Ответ 14

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

Ответ 15

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

Вот современный подход, работающий с PHP-FPM как Fast CGI, для которого не требуется правило переписывания .htaccess или переменная среды:

В php.ini или .user.ini оставьте буферизацию вывода включенной, чтобы разрешить использование функций ob_ *:

output_buffering = 1
zlib.output_compression = 0
implicit_flush = true
output_handler = 

В PHP-скрипте:

header('Content-Encoding: none'); // Disable gzip compression
ob_end_flush(); // Stop buffer
ob_implicit_flush(1); // Implicit flush at each output command

Смотрите этот комментарий на официальном PHP-документе для ob_end_flush().

Ответ 16

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

SetEnv no-gzip 1

Ответ 17

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

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

            output_buffering = Off
            zlib.output_compression = Off
            implicit_flush = Off

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

implicit_flush = On

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