Как сбросить вывод после каждого вызова `echo`? - PullRequest
51 голосов
/ 28 июня 2010

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

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

PS: этонемного грязно, чтобы добавить очистку в конце вызова echo ...

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

Ответы [ 17 ]

1 голос
/ 18 января 2019

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

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

В php.ini или .user.ini:

output_buffering = 0
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 ().

1 голос
/ 27 июня 2018

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

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

SetEnv no-gzip 1
0 голосов
/ 19 сентября 2014

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

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;
0 голосов
/ 02 октября 2017

Это мой код: (работает для 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();
}
0 голосов
/ 06 августа 2017

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

Лучшее решение - отключить deflate, 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 ();в вашем коде больше.

0 голосов
/ 17 апреля 2017

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

...