PHP Flush() не работает в Chrome

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

function buffer_flush(){

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

    if(ob_get_length()){

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

    }

    @ob_start();
}

Ответ 1

Вот как я получил 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>; Я писал страницу с нуля.

Ответ 2

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

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

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

    function buffer_flush(){
      echo '<!-- -->'; // ?
    
      ob_flush();
      flush();
    }
    

Ответ 3

Некоторые браузеры (как минимум, и, возможно, хром) требуют определенного количества "полезных" символов (т.е. не пробелов) до вывода чего-либо. В случае 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()

Ответ 4

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

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

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

После ввода следующих двух кодовых строк каждая эхо-команда сразу же нажимает текст на все-PHP-сервер:

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

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

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

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

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

EDIT: Если у вас включен gzip, весь ответ с сервера будет буферизирован.

Ответ 5

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

Но я не знаю, почему хром не сливается иначе.

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

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

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

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

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

начало... для сна... отображается бодрствование и завершается script.

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

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

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

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

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

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

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

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

вот скриншот readystate - responseetext из приведенного выше PHP скрипт

enter image description here

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

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

так... Хром только знает.

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

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

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

и

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