PHP Flush () не работает в Chrome - PullRequest
11 голосов
/ 14 мая 2011

Я наткнулся на эту функцию, которая обещала работать через IE, FF и Chrome. Но это не работает в Chrome. Есть ли работа вокруг?

function buffer_flush(){

    echo str_pad('', 512);
    echo '<!-- -->';

    if(ob_get_length()){

        @ob_flush();
        @flush();
        @ob_end_flush();

    }

    @ob_start();
}

Ответы [ 5 ]

9 голосов
/ 02 августа 2011

Вот как у меня работает flush () в цикле while в Chrome 12.0.742.122 с PHP 5.3.6:

echo("<html><body>");
while(1) {
  echo(str_pad($my_string_var,2048," "));
  @ob_flush();
  flush();
}

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

"@" не является строго необходимым, но предотвращает заполнение журнала сообщениями "ничего в буфере".

И, конечно, если у вас уже есть существующая страница, просто убедитесь, что там есть теги <html> и <body>;Я писал страницу с нуля.

4 голосов
/ 14 мая 2011

С flush() / ob_flush() вы только отправляете выходные данные в браузер, но они все еще остаются в браузере, когда он их отображает.Я предполагаю, что Chrome просто ждет, пока не получит достаточно данных, чтобы отобразить «полезную» страницу, а не некоторые фрагменты.

В любом случае некоторые предложения:

  • Избегайте использования @ (особенно, если вы точно не знаете, что он делает)
  • Если вы не звоните ob_end_*(), вам не нужно снова звонить ob_start().Неэффективно

    function buffer_flush(){
      echo '<!-- -->'; // ?
    
      ob_flush();
      flush();
    }
    
3 голосов
/ 14 мая 2011

Некоторые браузеры (по крайней мере, IE6 и, возможно, chrome) требуют определенного количества «полезных» символов (т.е. не пробелов) перед выводом чего-либо.В случае IE6 это даже размер сжатых данных, который необходимо передать.

function force_flush() {
    echo "\n\n<!-- Deal with browser-related buffering by sending some incompressible strings -->\n\n";

    for ( $i = 0; $i < 5; $i++ )
        echo "<!-- abcdefghijklmnopqrstuvwxyz1234567890aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz11223344556677889900abacbcbdcdcededfefegfgfhghgihihjijikjkjlklkmlmlnmnmononpopoqpqprqrqsrsrtstsubcbcdcdedefefgfabcadefbghicjkldmnoepqrfstugvwxhyz1i234j567k890laabmbccnddeoeffpgghqhiirjjksklltmmnunoovppqwqrrxsstytuuzvvw0wxx1yyz2z113223434455666777889890091abc2def3ghi4jkl5mno6pqr7stu8vwx9yz11aab2bcc3dd4ee5ff6gg7hh8ii9j0jk1kl2lmm3nnoo4p5pq6qrr7ss8tt9uuvv0wwx1x2yyzz13aba4cbcb5dcdc6dedfef8egf9gfh0ghg1ihi2hji3jik4jkj5lkl6kml7mln8mnm9ono -->\n\n";

    while ( ob_get_level() )
        ob_end_flush();

    @ob_flush();
    @flush();
} # force_flush()
1 голос
/ 17 апреля 2013

Я обнаружил, что заголовок типа контента действительно заставляет его работать в Chrome после нескольких проб и ошибок.

Но я не знаю, почему Chrome иначе не сбрасывается.

после поискабольше ответов Я прочитал, что Chrome сбрасывается, как вы ожидаете, только когда установлен правильный тип контента.хорошо.

Вот код, который я экспериментировал.

<?php
header('Content-Type: text/html; charset=UTF-8');

echo 'starting...';
flush();
echo 'to sleep...';
flush();
sleep(5);
echo 'awake';

, если я не включаю заголовок типа контента, я получаю, как показано ниже, в одном кадре через 5 секунд.так что мы ожидаем, не сработало.

Начинается ... для сна ... Просыпается отображается и сценарий завершается.

где, как если бы я дал тип контента, как указано выше, с подтипом (charset), то

запуск ... для сна ... отображается немедленно, а затем через 5 секунд отображается пробуждение.

Я просто слепо предполагаю, что в отношении заголовка типа содержимого хром отображает вывод.

Кроме того, когда я дал «Content-Type: text / plain» или «Content-Type: text / html», это не сработало.он работал только с подтипом 'charset = [sometexthere]'.

, как работало application / json.и я не экспериментировал с большим количеством мимов.

Причина, по которой я здесь,

Я хотел использовать readystate 3 в ответе ajax.он отлично работает, кроме хрома и сафари.так как chrome использует webkit, я думаю, что он одинаков в обоих.

в других браузерах, включая IE, сброс работает должным образом, а также readystate = 3, но в chrome и safari я только что использовал вышеуказанный обходной путь.

вот скриншот readystate - responsetext из приведенного выше php-скрипта

enter image description here

на изображении есть два набора ответов: первый с readystate 3 иответный текст как пустой, когда тип содержимого не используется.

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

, так что ... Chrome знает только.

при использовании str_pad

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

, если используется заполнение, и тип контента не установлен, то он не работал.

и

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

1 голос
/ 15 сентября 2011

Есть несколько компонентов, которые могут повлиять на эту проблему.

Внимательно прочитайте документацию по этой функции: http://www.php.net/manual/en/function.flush.php

Одно решение, которое у меня было, - это использование Apache2 с mod-php(не как fcgi, а как собственный apache-модуль) и Chromium.Результат пришел немедленно, и скрипт все еще работал и отправлял больше результатов.

После ввода следующих двух строк кода каждая команда echo немедленно отправит текст в what-PHP-backend :

ob_implicit_flush(1);
@ob_end_flush(); // set an end to the php-output-buffer!

Но этот PHP-бэкэнд может иметь свой собственный буфер.Например, я запускаю nginx как веб-сервер, а php используется модулем fast-cgi.Сам Nginx имеет свой собственный буфер ... и т. Д.

Браузер также может буферизовать запрос.Но, как я понимаю, Chromium (или Google Chrome) имеет очень маленький или нулевой буфер.

Пожалуйста, прочтите документацию по каждой функции, которую я упомянул, чтобы понять, что они на самом деле делают, но особенно документацию по flush () .

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

РЕДАКТИРОВАТЬ: Если у вас включен gzip, весь ответс сервера будут буферизованы.

...