ob_end_clean — очищает буфер вывода и отключает буферизацию вывода.


Содержание

Вывод буфера буферизации PHP-вывода

0 medk [2020-08-09 14:54:00]

Я должен выводить результаты во время работы PHP-скрипта:

Это работает, но бросает предупреждения:

Примечание: ob_end_flush(): не удалось удалить и сбросить буфер. Нет буфера для удаления или очистки.

Как это исправить?

3 ответа

В первом цикле вы заканчиваете буфер. Если вы хотите это сделать, вы должны запустить новый буфер в каждом цикле.

Это более простой способ использования буферизации. Он также более эффективен, поскольку вы используете только 1 буфер. Если вам не нужно flush на каждом цикле, вы можете пропустить ob_flush внутри цикла и использовать ob_end_flush вместо ob_end_clean .

1 FrankerZ [2020-08-09 15:02:00]

ob_end_flush() отключит буферизацию, поэтому будущие вызовы этого в вашем цикле не сработают. Просто используйте ob_flush() , который очищает буфер, но поддерживает буферизацию вывода:

Как отключить буферизацию вывода в PHP

Я написал простой скрипт реле, которое подключается к веб-камере и читает из сокета, и выводит эти данные с помощью функции печати. Данные MJPG данных с границами уже настройки. Я просто выводить данные, которые считываются.

Проблема заключается в PHP, как представляется, буферные эти данные. Когда я установил камеру на 1 FPS, подача замерзнет в течение 7-8 секунд, а затем быстро отображать 8 кадров. Если установить разрешение на огромный размер, перемещать камеру на более или менее 1 кадр в секунду. Я предполагаю, что тогда некоторые буферизация происходит (так как огромные размеры заполнения буфера быстро, и низкие размеры не делают), и я не могу понять, как отключить эту буферизацию. Кто-нибудь знает, как?

ТЛ; др версия

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

Во всем мире, либо .

    Выключение output_buffering в вашем php.ini, или

Выключение output_buffering в вашей Apache конфигурации с помощью

или просто сценарий, вы заботитесь о, либо .

  • вызова ob_end_flush() или
  • призвание ob_end_clean()

Кроме того, отключение выходного буфера на уровне сервера, насколько это возможно, либо:

  • вызывая 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 (или с помощью

в вашей Apache конфигурации, если вы используете Apache). Кроме того , вы можете отключить его для одного сценария по телефону ob_end_clean() или ob_end_flush() в начале сценария.

Буфер записи, а буфер веб-сервер

Помимо выходного буфера является то , что PHP руководство относится к как «буфер запись», плюс буферная система ваш веб — сервер имеет. Если вы используете PHP с Apache через mod_php , и не используется mod_gzip , вы можете позвонить , flush() чтобы смыть их; с другими движками, он может работать также, хотя руководство скрытное о предоставлении гарантии:

Описание

Очищает буферы записи из PHP и все, что бэкенд PHP использует (CGI, веб-сервер и т.д.). Это попытка подтолкнуть Токовый выход всего путь к браузеру с некоторыми оговорками.

Flush () не может быть в состоянии перекрыть схему буферизации вашего веба — сервер , и это не имеет никакого эффекта на любой сторону клиента буферизации в браузере. Он также не влияет на механизм буферизации вывода в пользовательском пространстве РНР. Это означает , что вы должны будете звонить как ob_flush () и флеш () для очистки выходных буферов О.Б. , если вы используете их.

Есть также несколько способов , которые вы можете сделать PHP автоматически вызывать flush() каждый раз , когда вы echo что — нибудь (или сделать что — нибудь еще , что перекликается выход к телу ответа).

Первый заключается в вызове ob_implicit_flush() . Обратите внимание , что эта функция обманчиво имени; учитывая его ob_ префикс, любой разумный человек будет ожидать , что это будет влиять на «выходной буфер», как это делают ob_start , и ob_flush т.д. Тем не менее, это не так; ob_implicit_flush() , Как flush() , влияет на выходной буфер уровня сервера и не взаимодействует каким — либо образом с выходным буфером под контролем других ob_ функций.

Буферизация вывода

Буферизация вывода в php достаточно важная и нужная тема. Допустим в какой-то момент php-скрипт производит вывод информации, но есть вероятность того, что в дальнейшем предстоит использовать функцию header() (Например header(«Loacation: /newaddress»)), которая в свою очередь уже не сработает, потому что вывод уже был. Другими словами можно использовать буферизацию php для того что-бы отложить вывод данных. Так-же можно разгрузить сервер от лишней нагрузки организовав html-кэширование, для этого понадобится записать весь вывод скрипта в файл, тут также должен использоваться механизм буферизации.

При выполнении данного скрипта, ничего не будет выведено на экран ( после инициализации буферизации ob_start() ничего не выводится на экран, до тех пор пока буферизация не будет выключена функцией ob_end_clean() ), потому что все данные были последовательно записаны с начала в переменную $out_data_1, а потом в $out_data_2.

Что-бы очистить буфер, используется функция ob_clean();

Как отключить буферизацию вывода в PHP

Я написал простой сценарий ретрансляции, который подключается к веб-камере и читает из сокета и выводит эти данные с помощью функции печати. Данные представляют собой данные MJPG с уже настроенными границами. Я просто выводим данные, которые читаются.

Проблема заключается в том, что PHP, похоже, выполняет буферизацию этих данных. Когда я устанавливаю камеру на 1 FPS, питание будет зависеть на 7-8 секунд, а затем быстро отобразит 8 кадров. Если я установил разрешение на огромный размер, камера будет двигаться более или менее 1 кадр в секунду. Я предполагаю, что тогда происходит буферизация (поскольку огромные размеры заполняют буфер быстро, а низкие – нет), и я не могу понять, как отключить эту буферизацию. Кто-нибудь знает, как это сделать?

Версия tl; dr

Сделайте две вещи:

Отключите буфер вывода пользовательского пространства, либо …

В глобальном масштабе, либо …

    Выключение функции output_buffering в php.ini или

Отключение output_buffering в вашей конфигурации Apache, используя

или просто для сценария, о котором вы заботитесь, либо …


Кроме того, отключите буфер вывода на уровне сервера столько, сколько вы можете, либо:

  • вызов 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 (или используя

в вашем Apache config, если вы используете Apache). Кроме того, вы можете отключить его для одного сценария, вызывая ob_end_clean() или ob_end_flush() в начале скрипта.

Буфер записи и буфер веб-сервера

Помимо выходного буфера – это то, что руководство PHP называет как «буфер записи», плюс любая система буферизации, которую имеет ваш веб-сервер. Если вы используете PHP с Apache через mod_php и не используете mod_gzip , вы можете вызвать flush() чтобы очистить их; с другими бэкендами, это тоже может сработать, хотя руководство сдержанно дает заверения:

Описание

Сбрасывает буферы записи PHP и любые внутренние ресурсы PHP (CGI, веб-сервер и т. Д.). Это позволяет сделать текущие выходные данные в браузере с несколькими оговорками.

flush () не сможет переопределить схему буферизации вашего веб-сервера и не влияет на буферизацию на стороне клиента в браузере. Он также не влияет на механизм буферизации вывода пользовательского пространства PHP. Это означает, что вам придется вызывать оба ob_flush () и flush (), чтобы очистить выходные выходные буферы, если вы их используете.

Существует также несколько способов, с помощью которых PHP может автоматически вызывать flush() каждый раз, когда вы echo отзываете что-либо (или делать что-либо еще, что выводит результат на тело ответа).

Первый – вызов ob_implicit_flush() . Обратите внимание, что эта функция обманчиво названа; учитывая его префикс ob_ , любой разумный человек ожидает, что он повлияет на «выходной буфер», как и ob_flush , ob_flush и т. д. Однако это не так; ob_implicit_flush() , например flush() , влияет на выходной буфер на уровне сервера и никак не взаимодействует с выходным буфером, контролируемым другими функциями ob_ .

Второй – глобальное включение неявной промывки, установив флаг implicit_flush в On в вашем php.ini. Это эквивалентно вызову ob_implicit_flush() в начале каждого скрипта. Обратите внимание, что руководство советует против этого, загадочно ссылаясь на «серьезные последствия для производительности» , некоторые из которых я исследую в этом касательном ответе .

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

Мы можем предоставить приведенный ниже код в файле .htaccess для отключения буферизации вывода в PHP

Буферизация вывода может быть многослойной, и у меня были случаи, когда более ранний код делал несколько уровней. Это очистит их всех.

Я знаю, что этот вопрос немного устарел, но, вернувшись к этому вопросу, вы можете отключить буферизацию вывода на сценарии на основе сценария, например:

Это должно отключить всю буферизацию вывода для любого сценария, который следует за ней.

Отключение буфера вывода с помощью Apache и PHP-FPM через mod_proxy

Вывод контента, как только PHP сгенерирует его, будет нормальным, если использовать Apache с PHP в качестве модуля, так как вы можете просто отключить output_buffering в PHP и использовать flush () или implicit_flush (1). Это то, что я ранее использовал, и он работал нормально.

С тех пор, как я перешел на PHP-FPM, я столкнулся с проблемой, из-за которой я не могу заставить Apache (2.4) выводить содержимое PHP, пока весь сценарий не будет завершен. У меня все еще есть output_buffering и сброс на месте, но этого недостаточно. Apache не использует mod_gzip (и это в любом случае затронет и модуль PHP).


Nginx имеет возможность отключить proxy_buffering, который, читая комментарии других людей, исправляет это, но я не могу найти какой-либо способ сделать это в Apache.

Вот как PHP в настоящее время вызывается в Apache:

Документация Apache упоминает flushpackets (использованный выше), который, кажется, является тем, что нужно, но затем он также говорит, что он применим только к AJS на данный момент, а не ко всему прокси-контенту, поэтому он ничего не сделает в этом случае.

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

Короче говоря: кто-нибудь знает правильный способ заставить Apache отправлять контент PHP, как только он выводится, а не ждать завершения сценария?

Решение

Повторно разместив ответ, я только что опубликовал очень похожий вопрос здесь: Как отключить буферизацию с помощью apache2 и mod_proxy_fcgi?

Несколько заметок, поскольку я провел последние несколько часов, экспериментируя, чтобы найти ответ на этот вопрос:

  1. Это невозможно полностью отключить буферизацию вывода при использовании mod_proxy / mod_proxy_fcgi однако вы можете получать ответы в виде кусков.
  2. Судя по моим экспериментам, кажется, что порции должны быть не менее 4096 байт, прежде чем выходные данные будут сброшены в браузер.
  3. Вы Можно отключить буферизацию вывода с помощью mod_fastcgi или же mod_fcgi модуль, но эти моды не так популярны / широко используются в Apache 2.4.
  4. Если у вас есть mod_deflate включен и не установлен SetEnv no-gzip 1 для виртуального хоста / каталог / и т.д. это потоковые данные, тогда gzip не позволит буферу сбрасываться, пока запрос не будет завершен.

Я тестировал вещи, чтобы увидеть, как лучше всего использовать новую функциональность BigPipe в Drupal 8 для потоковой передачи запросов клиенту, и я опубликовал еще несколько заметок в этот вопрос GitHub .

Другие решения

Хак, чтобы заставить работать PHP FPM с Apache 2.4 mod_proxy:

  • вызовите ob_end_clean () в начале вашего PHP-скрипта
  • вызовите flush () как минимум 21 раз, чтобы очистить вывод, вместо того, чтобы вызывать его один раз; всегда отправляйте хотя бы один символ между вызовами flush ()

использование ob_end_clean () без ob_start () не имеет смысла для меня, но, кажется, помогает — и возвращает true (= успех!)

Контроль вывода

Здесь я расскажу об очень удобном механизме — вывод в буфер. Мне частенько попадается код вроде:

И это сильно упрощенный пример. Кода здесь может быть много. А теперь приведу тоже, с использованием функций контроля вывода:

Функция ob_start(); включает буферизацию вывода, а функция ob_get_clean(); возвращает буфер в виде строки и отключает буферизацию. Есть и другие Функции контроля вывода, но ими мне пользоваться не приходилось, поэтому ограничусь ссылкой.

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

Как отключить буферизацию вывода в PHP

Я написал простой сценарий ретрансляции, который подключается к веб-камере и читает данные из гнезда и выводит эти данные с помощью функции печати. Данные являются данными MJPG с уже установленными границами. Я просто вывести данные, которые читаются.

Проблема в том, что PHP, похоже, буферизует эти данные. Когда я установлю камеру на 1 FPS, подача будет зависать на 7-8 секунд, а затем быстро отображать 8 кадров. Если я установлю разрешение огромного размера, камера будет двигаться с более или менее 1 кадром в секунду. Я предполагаю, что тогда происходит некоторая буферизация (поскольку большие размеры быстро заполняют буфер, а малые — нет), и я не могу понять, как отключить эту буферизацию. Кто-нибудь знает как?

Илон Маск рекомендует:  Что такое код ncurses_savetty

5 ответов

Возможно, для Вашего проекта будут необходимы бесплатные векторные карты. На нашем сайте представлены карты для всех стран.

tL; Dr версия

Сделать две вещи:

Отключите буфер вывода пользовательского пространства, либо.


Во всем мире, либо.

    Выключение output_buffering в вашем php.ini, или

Выключение output_buffering в вашем конфиге Apache, используя

или только для сценария, который вас интересует, либо.

  • призвание ob_end_flush() , или же
  • призвание ob_end_clean()

Кроме того, отключите буфер вывода на уровне сервера, насколько это возможно, одним из следующих способов:

  • призвание 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 (или используя

в вашей конфигурации Apache, если вы используете Apache). Кроме того, вы можете отключить его для одного скрипта, вызвав ob_end_clean() или же ob_end_flush() в начале сценария.

Буфер записи и буфер веб-сервера

Помимо выходного буфера есть то, что в руководстве по PHP называется «буфер записи», плюс любая система буферизации, которую имеет ваш веб-сервер. Если вы используете PHP с Apache через mod_php , и не используют mod_gzip , ты можешь позвонить flush() очистить их; с другими бэкэндами это тоже может сработать, хотя в руководстве нет ничего общего с предоставлением гарантий:

Описание

Сбрасывает буферы записи 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() в начале каждого сценария. Обратите внимание, что руководство не советует этого, загадочно ссылаясь на «серьезные последствия для производительности», некоторые из которых я исследую в этом касательно связанный ответ.

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


Выходная буферизация может быть многоуровневой, и у меня были случаи, когда в предыдущем коде было несколько уровней. Это очистит их всех.

Мы можем дать приведенный ниже код в файле .htaccess для отключения буферизации вывода в PHP

Я знаю, что этот вопрос немного устарел, но возвращаясь к этому вопросу, вы можете отключить буферизацию вывода от сценария к сценарию, например так:

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

Как отключить буферизацию вывода в PHP

Я написал простой сценарий ретрансляции, который подключается к веб-камере и читает данные из гнезда и выводит эти данные с помощью функции печати. Данные являются данными MJPG с уже установленными границами. Я просто вывести данные, которые читаются.

Проблема в том, что PHP, похоже, буферизует эти данные. Когда я установлю камеру на 1 FPS, подача будет зависать на 7-8 секунд, а затем быстро отображать 8 кадров. Если я установлю разрешение огромного размера, камера будет двигаться с более или менее 1 кадром в секунду. Я предполагаю, что тогда происходит некоторая буферизация (поскольку большие размеры быстро заполняют буфер, а малые — нет), и я не могу понять, как отключить эту буферизацию. Кто-нибудь знает как?

5 ответов

TL; Dr версия

Сделать две вещи:

Отключите буфер вывода пользовательского пространства, либо .

Во всем мире, либо .

    Отключение output_buffering в вашем php.ini или

Отключение output_buffering в вашей конфигурации Apache с помощью

или только для сценария, который вас интересует, либо .

Кроме того, отключите буфер вывода на уровне сервера настолько, насколько это возможно, одним из следующих способов:

  • вызывая 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 (или используя

в вашей конфигурации Apache, если вы используете Apache). Кроме того, вы можете отключить его для одного скрипта, вызвав ob_end_clean() или ob_end_flush() в начале скрипта.


Буфер записи и буфер веб-сервера

Помимо выходного буфера есть то, что в руководстве по PHP называется «буфер записи», плюс любая система буферизации, которую имеет ваш веб-сервер. Если вы используете PHP с Apache через mod_php и не используете mod_gzip , вы можете вызвать flush() для их очистки; с другими бэкэндами это тоже может сработать, хотя в руководстве говорится о том, чтобы давать гарантии:

Описание

Сбрасывает буферы записи PHP и того, что использует PHP для бэкэнда (CGI, веб-сервер и т. Д.). Это пытается выдвинуть текущий вывод в браузер с несколькими предостережениями.

flush () может не иметь возможности переопределить схему буферизации вашего веб-сервера, и это не влияет на буферизацию на стороне клиента в браузере. Это также не влияет на механизм буферизации вывода пользовательского пространства PHP. Это означает, что вам придется вызывать оба метода ob_flush () и flush () для очистки выходных буферов ob, если вы их используете.

Илон Маск рекомендует:  Что такое код delphixml

Есть также несколько способов, которыми вы можете заставить PHP автоматически вызывать flush() каждый раз, когда вы что-то echo (или делаете что-то еще, что выводит вывод в тело ответа).

Первый — вызвать ob_implicit_flush() . Обратите внимание, что эта функция обманчиво названа; учитывая его префикс ob_ , любой разумный человек мог бы ожидать, что это повлияет на «выходной буфер», как это делают ob_flush , ob_flush и т. д. Однако это не так; ob_implicit_flush() , как и flush() , влияет на выходной буфер уровня сервера и никак не взаимодействует с выходным буфером, управляемым другими функциями ob_ .

PHP: Буферизация вывода

Буферизация вывода в PHP это довольно полезная штука, если уметь ею пользоваться. Скажите сколько раз вы видели ошибки типа:

Warning: Cannot modify header information — headers already sent by (output started at …)

Как правило подобное случается, если вы хотите отправить куки, или выполнить операции, которые способствуют их отправке, или иные операции способствующие отправке заголовков, например запуск сессии или применение функции header или подобных. Или ваш файл в кодировке юникод и в самом его начале притаилась BOM — метка порядка байтов. Это подлющая штука есть неразрывный пробел с нулевой шириной. Смотрим здесь под заголовком «Порядок байтов».

Всё очень просто: По — умолчанию никакой буферизации вывода нет ( если, конечно вы не нашаманили в файле php.ini и не присвоили директиве output_buffering значение On ) и PHP отсылает данные юзеру, сразу, как только они готовы. Согласно протоколу HTTP, сервер в ответ на запрос пользователя, должен сначала отправить ему служебные заголовки, а уже после, тело страницы. А тут внезапно, в коде вы опять пытаетесь заставить его отправить HTTP — заголовки, вызывая, скажем функцию session_start() — после удачной авторизации… Ясен пень — повторная отправка заголовков запрещена, HTTP — протокол так не работает! Но что ж делать то? Если после вывода на странице, нужно ещё и сессию стартануть и кУку поставить? — Вспоминаем про буферизацию вывода.

Возможности при буферизации

Используя буферизацию вывода мы можем:

  • Посылать cookie из любого места в скрипте.
  • Стартовать сессию в любой момент.
  • Сжимать данные, перед отправкой их пользователю.

Сжатие дополнительно нагружает процессор, тем не менее объем трафика на одну страницу уменьшится примерно процентов на сорок, а это значит, что сервер потратит меньше времени на пересылку данных по сети. Величина сжатия зависит от многих факторов, например картинки сжимаются хуже чем текст.

Что происходит при буферизации?

При буферизации вывода, механизм PHP складывает в стопку весь вывод скрипта, паралельно формируя пакет HTTP — заголовков, в том числе, добавляя туда и заголовки «cookie» и любые другие, которые получатся в результате работы вашего скрипта. А потом, когда скрипт отработал он берёт и отправляет всё это клиенту в правильном порядке: сначала заголовки, а потом страницу — результат работы скрипта.

Как включить буферизацию вывода?

Первый способ это если сервак ваш, или у вас просто есть доступ к файлу php.ini ( как я писал выше ) ищем в нём директиву output_buffering и присваиваем ей значение On. Это включит буферизацию для всех скриптов.

Второй способ это использовать функцию ob_start() в скрипте, вывод которого нам нужно буферизовать. Этот способ предпочтительней — вы получите большую гибкость/контроль в работе, а так же лучшую переносимость.

На мой взгляд довольно удобно рассматривать буферизацию вывода, в виде неких контейнеров — буферов. Так проще понять их работу.

Итак, открыть такой контейнер — буфер можно лишь одной функцией ob_start(), а вот закрыть этот самый буфер можно двумя функциями: ob_end_flush() и ob_end_clean()

Закрывает буфер и отправляет данные.

Закрывает буфер без отправки данных.

Все содержимое, которое выводиться в тот момент, когда буфер открыт попадает в буфер и никуда не отсылается. Например:

Как отключить буферизацию вывода в PHP

Я написал простое реле script, которое подключается к веб-камере и считывает из сокета и выводит эти данные с помощью функции печати. Данные представляют собой данные MJPG с уже настроенными границами. Я просто выводю данные, которые читаются.


Проблема заключается в том, что PHP, похоже, выполняет буферизацию этих данных. Когда я устанавливаю камеру на 1 FPS, питание будет зависеть на 7-8 секунд, а затем быстро отобразит 8 кадров. Если я установил разрешение на огромный размер, камера будет двигаться более или менее 1 кадр в секунду. Я предполагаю, что тогда происходит буферизация (поскольку огромные размеры заполняют буфер быстро, а низкие — нет), и я не могу понять, как отключить эту буферизацию. Кто-нибудь знает как?

5 ответов

tl; dr версия

Сделайте две вещи:

Отключите буфер вывода пользовательского пространства, либо.

В глобальном масштабе, либо.

    Отключение output_buffering в вашем php.ini или

Отключение output_buffering в вашей конфигурации Apache с помощью

или только для script, о котором вы заботитесь, либо.

Также отключите буфер вывода на уровне сервера как можно больше:

  • вызов 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(или используя

в вашей конфигурации Apache, если вы используете Apache). Кроме того, вы можете отключить его для одного script, вызывая ob_end_clean() или ob_end_flush() в начале script.

Буфер записи и буфер веб-сервера

Помимо выходного буфера, это то, что руководство PHP называет как «буфер записи», плюс любая система буферизации, которую имеет ваш веб-сервер. Если вы используете PHP с Apache через mod_php и не используете mod_gzip , вы можете вызвать flush() , чтобы очистить их; с другими бэкендами, это тоже может сработать, хотя руководство сдержанно дает заверения:

Описание

Сбрасывает буферы записи PHP и любые внутренние ресурсы PHP (CGI, веб-сервер и т.д.). Это пытается вытолкнуть текущий вывод полностью в браузер с несколькими оговорками.

flush(), возможно, не сможет переопределить схему буферизации вашего веб-сервера и не влияет на буферизацию на стороне клиента в браузере. Он также не влияет на механизм буферизации вывода пользовательского пространства PHP. Это означает, что вам нужно будет вызвать ob_flush() и flush(), чтобы очистить выходные выходные буферы, если вы используя их.

Существует также несколько способов, с помощью которых PHP может автоматически вызывать flush() каждый раз, когда вы echo что-либо (или делать что-либо еще, что выводит результат на тело ответа).

Первое — вызвать ob_implicit_flush() . Обратите внимание, что эта функция обманчиво названа; учитывая его префикс ob_ , любой разумный человек ожидал бы, что он повлияет на «выходной буфер», как и на ob_start , ob_flush и т.д. Однако это не так; ob_implicit_flush() , как и flush() , влияет на выходной буфер на уровне сервера и никак не взаимодействует с выходным буфером, управляемым другими функциями ob_ .

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL