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.