Как отключить буферизацию вывода в nginx для приложения PHP
У нас есть код, похожий на этот:
<?php
ob_implicit_flush(true);
ob_end_flush();
foreach ($arrayOfStrings as $string) {
echo time_expensive_function($string);
}
?>
В Apache это отправит каждое эхо в браузер по мере его выхода. Однако в nginx/FastCGI это не работает из-за того, что nginx работает (по умолчанию).
Возможно ли сделать эту работу над nginx/FastCGI, и если да, то как?
Ответы
Ответ 1
Ни один из вышеперечисленных решений не работал у меня.
Первый php должен правильно очистить все:
@ob_end_flush();
@flush();
Затем я нашел два рабочих решения:
1) Через конфигурацию Nginx:
fastcgi_buffering off;
2) Через HTTP-заголовок в php-коде
header('X-Accel-Buffering: no');
Ответ 2
Простое решение:
fastcgi_keep_conn on; # < solution
proxy_buffering off;
gzip off;
Ответ 3
Мне не нужно было отключать gzip для всего сервера или целого каталога, всего лишь для нескольких скриптов, в нескольких конкретных случаях.
Все, что вам нужно, это прежде, чем что-то будет эхо-сообщение:
header('Content-Encoding: none;');
Затем выполните флеш как обычно:
ob_end_flush();
flush();
Nginx, похоже, забирает кодировку, отключенную и не gzip.
Ответ 4
Добавьте функцию flush() в ваш цикл:
foreach ($arrayOfStrings as $string) {
echo time_expensive_function($string);
flush();
}
Это может сработать, но не обязательно на каждой итерации (там какая-то магия!)
Ответ 5
Добавить -flush в конфигурацию FastCGI, см. руководство:
Из http://mailman.fastcgi.com/pipermail/fastcgi-developers/2009-July/000286.html
Ответ 6
Мне понадобились обе эти строки в начале моего сценария:
header('X-Accel-Buffering: no');
ob_implicit_flush(true);
Каждая строка также будет работать, объединяя их, мой браузер получит результаты с сервера еще быстрее. Не могу объяснить это, просто пережил это.
Моя конфигурация - nginx с php-fpm.