tl; dr version
Сделайте две вещи:
Отключите буфер вывода пользовательского пространства, либо ...
Также отключите буфер вывода на уровне сервера, насколько это возможно, одним из следующих способов:
- вызов
ob_implicit_flush()
в начале вашего скрипта или - вызов
flush()
после каждого оператора echo
или другого оператора, который добавляет вывод в тело ответа
Более длинная версия
Возможно, существуют два уровня буферизации, которые могут иметь значение, и документация PHP плохо справляется с различием между ними.
Выходной буфер
Первый уровень обычно упоминается в документации PHP как «буфер вывода».Этот уровень буферизации влияет только на вывод тела ответа HTTP, а не на заголовки.Вы можете включить выходную буферизацию с помощью ob_start()
и отключить ее с помощью ob_end_flush()
или ob_end_clean()
.Вы также можете автоматически запускать все ваши сценарии с буферизацией при использовании опции output_buffering
в php.ini.
Значение по умолчанию для этой опции для производственных версий php.ini равен 4096, что означает, что первые 4096 байт выходных данных будут буферизованы в выходном буфере, после чего он будет сброшен, а выходная буферизация отключена.
Вы можете отключить этот слойглобальной буферизации, установив output_buffering
в Off
в вашем файле php.ini (или используя
php_flag "output_buffering" Off
в вашей конфигурации Apache, если вы используете Apache).Кроме того, вы можете отключить его для отдельного сценария, вызвав ob_end_clean()
или ob_end_flush()
в начале сценария.
Буфер записи и буфер веб-сервера
За пределами выходного буфераэто то, что в руководстве по PHP называется «буфер записи», плюс любая система буферизации, которую имеет ваш веб-сервер.Если вы используете PHP с Apache через mod_php
и не используете mod_gzip
, вы можете вызвать flush()
, чтобы очистить их;с другими бэкэндами это тоже может сработать, хотя в руководстве не хватает гарантий:
Описание
void flush ( void )
Сбрасывает буферы записи PHP и любого используемого бэкэндом PHP (CGI, веб-сервер и т. Д.).Это попытка протолкнуть текущий вывод в браузер с несколькими предостережениями.
flush () , возможно, не сможет переопределить схему буферизации вашего веб-сервера, и это не имеет никакого эффектана любую клиентскую буферизацию в браузере.Это также не влияет на механизм буферизации вывода пользовательского пространства PHP.Это значит, что вам придется вызывать ob_flush () и flush () , чтобы очистить выходные буферы ob, если вы их используете.
Естьтакже есть несколько способов заставить PHP автоматически вызывать flush()
каждый раз, когда вы echo
что-нибудь делаете (или делаете что-либо еще, что выводит вывод в тело ответа).
Первое - это вызвать ob_implicit_flush()
.Обратите внимание, что эта функция обманчиво названа;учитывая его префикс ob_
, любой разумный человек может ожидать, что это повлияет на «выходной буфер», как это делают ob_start
, ob_flush
и т. д. Однако это не так;ob_implicit_flush()
, как и flush()
, влияет на выходной буфер уровня сервера и никак не взаимодействует с выходным буфером, управляемым другими функциями ob_
.
Вторым является глобальное включение неявной очистки, установив флаг implicit_flush
на On
в вашем php.ini.Это эквивалентно вызову ob_implicit_flush()
в начале каждого скрипта.Обратите внимание, что руководство не советует этого, загадочно цитируя «серьезные последствия для производительности» , некоторые из которых я исследую в этом тангенциально связанном ответе .