ob_get_contents — возвращает содержимое буфера вывода


LXXIV. Функции управления выводом

Функции управления выводом позволяют определять, когда вывод будет отправлен из скрипта. Это можно использовать в различных ситуациях, особенно если вам нужно выслать шапки/headers браузеру, после того как ваш скрипт начал выводить данные. Функции управления выводом не влияют на шапки, высылаемые функциями header() или setcookie() , только на такие функции, как echo() , и на данные между блоками PHP-кода.

Пример 1. Управление выводом

В приведённом примере вывод из echo() будет сохранён в буфере вывода, пока ob_end_flush() не будет вызвана. Тем временем вызов setcookie() успешно сохранил cookie без возникновения ошибки. (Вы не можете нормально отправить шапки/headers браузеру, после того как данные уже были отправлены.)

PHP ob_get_contents & quot; иногда & quot; возвращается пустым когда не должно?

Выпуск: Я наблюдаю случайную ситуацию, когда ob_get_conents () ничего не возвращает, когда он ДОЛЖЕН иметь что-то. Не удается несколько из тысяч успехов каждый день. Случайным образом.

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

Увидев несколько проблем с пустой страницей, я обнаружил, что ob_get_contents () ничего не возвращал для данного обновления. Когда это обновлялось в следующий раз, это обычно было нормально. Затем, на ровном месте, пустое возвращение снова через несколько часов (никогда в одно и тоже время).

Это сводит меня с ума, потому что это не соответствует. У меня есть действие php, напишите мне, когда возврат из ob_get_contents () пуст … с кучей деталей. Ничто, кажется, не проливает свет на «почему».

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

Некоторые другие детали:

  • Версия PHP 5.5.9-1ubuntu4.19 (возможно, ошибка в этой версии?)
  • output_buffering 4096
  • ob_get_level () всегда возвращает «2»
  • Генерация HTML варьируется от 10 КБ до 92 КБ, в зависимости от того, какая часть
  • Не всегда встречается в одной и той же части HTML
  • Все это были хиты, которые не прошли ни POST, ни GET.

Большинство таких агентов (все случайные IP-адреса):

  • «Рубин»
  • «Mo% 20PTT / 2020092702 CFNetwork / 808.0.2 Darwin / 16.0.0»
  • «FeedBurner / 1.0»

Пожалуйста, обратите внимание: Это не всегда возвращая пустое, как и другие вопросы о стеке, об ob_get_contents (). Я их перечитал, там никакой помощи … Хотелось бы, чтобы это было всегда, тогда это было бы очевидным решением.

Решение

Я был свидетелем подобной проблемы в той же версии PHP (5.5.9) в течение нескольких месяцев. Также не может переключиться на другую версию PHP.
Я изо всех сил пытался даже обнаружить это в нашей системе, но, к счастью, прямо сейчас смог отследить и использовать его.

В PHP 5.5.9 функция print_r внутренне использует буферизацию вывода, и в этой версии сообщается об ошибках, print_r и буферизация вывода.

Итак, вот что вам нужно сделать ..

Создайте скрипт first.php:

Создайте еще один скрипт second.php:

Что здесь происходит:

Первый скрипт просто выводит некоторые символы в цикле. И он делает это, повторяя 10 символов на каждой итерации. Если вы просто вызовете этот скрипт, он всегда будет превышен по истечении заданного времени.

Второй скрипт вызывает первый с помощью CURL, но отключенным способом (1 секунда). Вот почему первый скрипт содержит игнорирование прерывания пользователя.

Каким-то образом, скорее всего, из-за некоторых ошибок, характерных для php версии 5.5.9, после того, как уже было выведено около 1,8 МБ данных, print_r и, таким образом, прекращается любое дополнительное использование буферизации вывода. Print_r со вторым параметром TRUE ничего не возвращает. Скорее всего, какой-то внутренний или системный буфер исчерпан, дополнительные символы никуда не помещаются, или уже отображенные символы отбрасываются. Не знаю Я не смог найти корреляцию между пороговым числом и любым параметром конфигурации из phpinfo. Выходная буферизация не имеет значения, установленного в нашей системе.

Мои рекомендации

Таким образом, может случиться так, что какой-то CURL / WGET использовался и отключался, или обычный браузер использовался и отключался только в начале. Такие имена, как «Ruby», «FeedBurner» для меня звучат как libs или роботы.

a) Если ваш скрипт не слишком сложен, попробуйте избежать буферизации вывода в PHP 5.5.9, а также print_r. var_export в порядке, работает по-другому.

b) Замените эхо-запросы конкатенацией строк, непосредственно к записи в файл, при генерации вывода. Если вы используете smarty, то это может оказаться невозможным, потому что smarty часто использует внутреннюю буферизацию вывода.

в) Или создайте список запрещенных агентов, если они составляют большинство за эти неудачи.

г) кстати. если ваш ob_get_level () возвращает 2, это означает, что буферизация вывода в вашей системе по умолчанию включена. Я думаю, что вам не нужно это для вашей задачи, отключение может даже помочь вам. Стоит попробовать.

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

Илон Маск рекомендует:  Эмуляция директивы register_globals on

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

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

Принцип работы буфферизированного вывода в php?

Начал изучать систему функции ob_* в php. Есть вопрос по нижеследующему коду:

Я намеренно закомментировал ob_end_flush(), так как если я правильно понял ob_start() буфферирует вывод, а ob_end_flush() выводит весь этот буфер. То есть на браузер ничего не должно выводится, не так ли?

Но у меня выводится

С Уважением,
Алмик

  • Вопрос задан более трёх лет назад
  • 2316 просмотров

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

Я обычно с буфером так работаю:

Хотя, можно ещё проще делать: вместо связки ob_get_contents + ob_end_clean можно использовать ob_get_clean, которая очищает буфер и при этом возвращает его содержимое.

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

PHP буферизация

Слово буферизация говорит само за себя, это значит, что мы что-то копируем, помещаем в буфер. В php, буферизация позволяет скопировать определенную часть выводимого контента (html) в браузер, обработать ее нужными нам функциями и показать его пользователю. Зачем это нам? Например, можно реализовать сжатие html кода, или замены некоторых сущностей на другие, да что угодно. Более детально рассмотрим применение php буферизации в последнем пункте статьи.

Реализация буферизации вывода в PHP

Буферизация начинается с функции ob_start([callback]);. После ее объявления буферизироваться будет все, что выводится в окно браузера. Аргумент callback это пользовательская функция, через которую можно пропустить и обработать выводимый текст, она должна возвращать одну строку.

ob_end_clean(); — завершает буферизацию и чистит буфер, но в браузер ничего не посылается.

Существует много функций для работы с буферизацией вывода в php. Сейчас посмотрим маленький практический пример для большей ясности дела. Например, у Вас генерируется страница, но при этом необходимо в тексте страницы заменить все буквы «ё» на буквы «е. Тогда делается примерно такое:

$page = str_replace(«ё», «е», $page);

Применение буферизации вывода

Рассмотрим некоторые практические стороны применения буферизации вывода. Как уже упоминалось, предположительно мы имеем часть выводимого html кода или весь выводимый код. Что же с ним можно сделать?

Реализация автообновления на вашем сайте.

Обновление в смысле обновление контента. Посмотрев лекции Каширина, я узнал, что для того, что-бы страничка сайта была обновляемой в глазах поискового робота, необходимо, что-бы 25% содержимого страницы поменялось коренным образом. В начале, я просто создавал блок анонса, который выводил 25% символов от статьи, блок был одним и тем же на всех страницах, обновлялся 1 раз в сутки, выбирался случайным образом из массы всех статей. Он выглядел таким образом:

Но здесь была проблемка, одна статья была на 1500 символов, другая на 10000 символов, и если анонсом выбиралась та, что на 10000 символов, и анонс отображался на той статье в которой 1500 символов, то получалось что блок анонса составлял 5000 символов, это гораздо больше, нежели сама статья. Может, вы думаете, что нужно было, узнать количество символов исходной статьи и вывести в 4 раза меньше в анонсе. Я тоже так думал, но есть еще много факторов, таких как комментарии, новости сайта… В общем, нужно было знать количество символов всей странички, в этом мне помогла php буферизация или php буферизация вывода, называйте как хотите. Ниже код как я это реализовал.

В файле anons.php, узнаем количество символов контента страницы без html тегов используя функции strip_tags() и strlen(). Далее дело техники, вычисляем блок анонса, его html код пишем в $show_anons и прицепляем после буферизированного контента ($buffer). Вот так вот мне помогла буферизация вывода в php. Ниже, скриншоты блока анонса, написанного с помощью использования php буферизации.

Вполне приличные блоки анонсов. Автообновление странички организовано, кричу УРА php буферизации.

Сжатие html кода

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

Другие варианты

Как видите применению буферизации вывода в php, нет предела. Наверняка у вас уже появились свои идеи, как реализовать те или иные штучки на своем сайте. Спасибо за внимание, надеюсь моя статья была вам полезной. Кстати, если имеете еще идеи по поводу применения php буферизации, пишите в комментариях ниже.

Кэширование страниц в PHP

Здравствуйте дорогие коллеги и просто читатели. Если Вы решили прочитать эту статью значит Вас как и меня волнует проблема кэширования страниц и тем самым ускорение их загрузки. Многие после того как начинают изучать язык веб-программирования стремятся создать что — нибудь своё уникальное и скорее выложить для всеобщего пользования в Интернет, но большинство не заботится о функциональности своих приложений. Поэтому данная статья нацелена на помощь в увеличении функциональности ваших программ, хотя бы со стороны быстроты загрузки страниц.

Из-за того что многие интернет пользователи, особенно в России выходят в Интернет через обычный модем, а скорость как Вы знаете полное г…. Загрузки страниц через модем происходит со скорость в среднем 4 кБ в секунду, представте если вы загружаете страницу весом 60 кБ или ещё хуже 100 кБ, то ожидать вам придёться от 15 до 25 секунд. А если сюда приплюсовать большое количество sql запросов в скрипте и возможно неоптимизированный код то…..

Поэтому я предлагаю кэшировать страницы с помощью класса WebCachePage_v_1.0. Подробно описывать все функции класса я не буду, а расскажу принцип работы класса и как им пользоваться. С кодом я думаю Вы и сами разберётесь.

Изначально класс создавался как дополнение к обработчику шаблонов WebTemplate_v_1.1 (в скором времени я представлю его Вам). Принцип работы класса основан на трёх стандартных функциях php:
ob_start() — включает буферизацию вывода данных.
ob_get_contents() — возвращает содержимое буфера (можно загнать в переменную).
ob_end_clean() — очищает буфер вывода и отключает буферизацию вывода.

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

C помощью функции ob_start() — буферизируем контент файла, потом с помощью функции ob_get_contents() загоняем контент файла в переменную и наконец очищаем буфер функцией ob_end_clean(). Код класса (к сожалению ссылку, чтобы его скачать дать не могу, так как нет сервера):

Для того чтобы начать работу с классом Вам необходимо создать каталог для кэшируемых файлов (по умолчанию cache). Затем включить класс в файл который будет кэшироваться с помощью функций include, require, но лучше всего require_once. После всех проделанных действий в начале документа Вам необходимо объявить класс и вызвать функцию буферизации:

Далее идёт сам файл который будем кэшировать и в конце файла вызывается главная функция кэширования:

Если вы вдруг захотите отчистить весь каталог с кэшируемыми файлами для этого есть специальная функция

Для работы с функцией вам необходимы два параметра $type — задаёт тип отчистки каталога (all — весь каталог, file — отдельный файл). Если вдруг вы захотите удалить отдельный файл с кэшем Вам необходимо в параметре $type указать file, а в параметре $file — имя файла.

Работа с буфером вывода во время выполнения callback-функции ob_start()

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

«Я встроил тебе ob-функцию внутрь ob-функции, чтобы ты мог редактировать буфер пока редактируешь буфер»

Внутри такого callback’а функции семейства ob уже не вызываются. И вообще если внутри этого callback’а вызвать хотя бы 1 echo — на экран браузера не выведется ничего, ни буфера, ни ошибки, ни варнинга, просто белый лист. Генерировать динамично html’ку налету в строковую переменную не хочу. Есть какие-нибудь варианты решения этой проблемы?

1 ответ 1

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

Я бы предложил другой вариант: создать два последовательных буфера. При помощи первого вы создаете переменную $template , в которой сохраняете шаблон. Второй буфер формируется по вашей схеме — с использованием функции обратного вызова (в примере ниже она оформлена как анонимная). Так как такая функция может принимать только один аргумент, эту переменную можно передать через замыкание use . В момент вызова функции ob_end_flush() , сработает анонимная функция, которая передается ob_start() , где вы и задействуете $template .

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

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

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

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

Справочник по PHP (37 стр.)

virtual

Имитация include virtual.

Синтаксис:


int virtual(string $url)

Функция virtual() представляет собой процедуру, которая может поддерживаться только в случае, если PHP установлен как модуль Apache. Она делает то же самое, что и SSI-инструкция . Иными словами, она генерирует новый запрос серверу, обрабатываемый им обычным образом, а затем выводит данные в стандартный поток вывода.

Чаше всего функция virtual() используется для запуска внешних CGI-сценариев, написанных на другом языке программирования, или же для обработки SSI-файлов более сложной структуры. В случае, если запускается сценарий, он должен генерировать правильные HTTP-заголовки, иначе будет выведено сообщение об ошибке. Для включения обычных PHP-файлов с участками кода функция virtual() неприменима — это выполняет оператор include.

Управление выводом

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

Эти функции не воздействуют на заголовки, посланные функциями header() или setcookie(), а только на функции, подобные echo() и HTML-тексту между блоками PHP-кода.

В примере выше вывод командой echo() будет сохранен в буфере вывода до вызова функции ob_end_flush(). В то же время вызов setcookie() успешно сохраняет cookie, не вызывая ошибки.

Введение

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

Эти функции не воздействуют на заголовки, посланные функциями header() или setcookie(), а только на функции, подобные echo() и HTML-тексту между блоками PHP-кода.

В примере выше вывод командой echo() будет сохранен в буфере вывода до вызова функции ob_end_flush(). В то же время вызов setcookie() успешно сохраняет cookie, не вызывая ошибки.

Функции управления выводом

ob_start

Включение буферизации вывода.

Синтаксис:

void ob_start([string output_callback])

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

Содержимое буфера может быть скопировано в строковую переменную функцией ob_get_contents(). Для вывода содержимого из буфера используется функция ob_end_flush(). Удалить содержимое буфера позволяет функция ob_end_clean().

Илон Маск рекомендует:  Sound package пакет работы со звуком

В аргументе output_callback можно указать функцию, которая будет автоматически вызываться при выводе содержимого буфера. Обычно это используется для модификации содержимого буфера перед выводом (например, сжатия). Тогда при вызове функции ob_end_flush() в указанную функцию будет передаваться содержимое буфера, а то, что она возвратит, будет выведено (заметьте, сама функция не должна ничего выводить).

Буферизация может быть вложенной, и тогда она обрабатывается соответственно вложенности; и содержимое, выводимое из буфера нижнего уровня, будет включаться в буфер верхнего уровня. Не забывайте, что для вывода всего буферизованного содержимого необходимо вызывать функцию ob_end_flush() столько же раз, сколько была вызвана ob_start().

Тут различный текст.

ob_get_contents

Получение содержимого буфера вывода.

Синтаксис:

Если буферизация неактивна, возвращается false.

ob_get_length

Получение длины данных в буфере вывода.

Синтаксис:

Если буферизация неактивна, возвращается false.

ob_end_flush

Вывод содержимого буфера.

Синтаксис:

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

flush

Вывод всего содержимого буфера.

Синтаксис:

Функция воздействует только на буферизацию PHP и не может контролировать схему буферизации web-сервера или браузера.

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

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

таблицы верхнего уровня.

ob_end_clean

Синтаксис:

Вызов функции отключает буферизацию на текущем уровне.

ob_implicit_flush

Установление режима буферизации.

Синтаксис:

void ob_implicit_flush([int flag]);

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

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

Управление исполнением сценария PHP

set_time_limit

Установка предельного времени исполнения сценария.

Синтаксис:

void set_time_limit(int seconds)

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

По умолчанию допустимое время исполнения сценария устанавливается в файле конфигурации параметром max_execution_time (обычно оно равно 30 с). Но для текущего сценария это время можно изменить вызовом данной функции, указав время в секундах в ее аргументе. Если указывается значение 0, то тогда временное ограничение снимается.

Отсчет времени начинается от момента вызова функции. Например, если сценарий уже выполнялся в течении 15 секунд, а затем вызывается функция set_time_limit(20), то общее максимальное время исполнения сценария становится равным 35 секундам.

Если сценарий выполняется в безопасном режиме (с установленным параметром safe mode), то тогда вызов этой функции игнорируется и используется значение из файла конфигурации.

sleep

Задержка выполнения сценария.

Синтаксис:

void sleep(int seconds);

Фукция sleep() выполняет задержку выполнения сценария в секундах (seconds).

usleep

Задержка выполнения сценария в микросекундах.

Синтаксис:

void usleep(int micro_seconds);

Задержка выполнения сценария в микросекундах (micro_seconds).

Эта функция не работает в Windows.

die

Вывод сообщения и завершение текущего сценария.

Синтаксис:

void die(string message);

Эта функция выводит сообщение и прекращает выполнение текущего скрипта. Не возвращает значение.

Функции управления выводом

Функции управления выводом

ob_start

Включение буферизации вывода.

Синтаксис:

void ob_start([string output_callback])

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

Содержимое буфера может быть скопировано в строковую переменную функцией ob_get_contents(). Для вывода содержимого из буфера используется функция ob_end_flush(). Удалить содержимое буфера позволяет функция ob_end_clean().

В аргументе output_callback можно указать функцию, которая будет автоматически вызываться при выводе содержимого буфера. Обычно это используется для модификации содержимого буфера перед выводом (например, сжатия). Тогда при вызове функции ob_end_flush() в указанную функцию будет передаваться содержимое буфера, а то, что она возвратит, будет выведено (заметьте, сама функция не должна ничего выводить).

Буферизация может быть вложенной, и тогда она обрабатывается соответственно вложенности; и содержимое, выводимое из буфера нижнего уровня, будет включаться в буфер верхнего уровня. Не забывайте, что для вывода всего буферизованного содержимого необходимо вызывать функцию ob_end_flush() столько же раз, сколько была вызвана ob_start().

return nl2br($str); // возвращает содержимое буфера

return strtoupper($str); // возвращает содержимое буфера

Тут различный текст.

// преобразовывать текст длее в верхний регистр

Php ob_get_contents() возвращает пустую строку, если включенный файл во время буферизации невелик

Скажем, у меня есть файл, состоящий из 5 строк текста, и каждая строка имеет 50 символов. Содержимое выходного буфера возвращается правильно, но если у меня есть файл, содержащий 100 строк текста, выходной буфер возвращает пустую строку (строка со значением null).

Я делаю это так:

Я делаю это внутри codeigniter, если это имеет значение.

Я попытался загрузить файл с помощью функции воспламенителя load-> view с третьим параметром, установленным в true, результат будет таким же. Пробовал также предоставление ob_start() большого числа → ob_start (9999999); такой же результат;

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

Довольно маловероятно, но что это делает вместо вашего кода?

Просто чтобы убедиться, что материал в file.php не окружен .

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

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