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