Буферизация вывода — одна из тех концепций в PHP, с которой достаточно часто сталкиваются разработчики, но мало кто задумывается, как она устроена. В статье рассказываем о том, что это за концепция в PHP и зачем ее использовать.
Эта статья — адаптированный перевод материала разработчицы Лары Шенк, опубликованного в ее личном блоге. Повествование ведется от лица автора.
Буферизация вывода в PHP — это способ указать, что нужно отдельно сохранить данные перед их отправкой в браузер. То есть данные можно получить, а затем поместить в переменную, работать с ними и уже позже отправлять в браузер.
Как-то раз мне на почту пришел вопрос про плагин Timber — я люблю использовать его при разработке сайтов на WordPress. У меня спросили: «Что делает header.php
и footer.php
в плагине Timber?». Быстрый ответ на этот вопрос: «Они ничего не делают», потому что они нужны для работы определенных плагинов в WordPress.
Однако я этого не знала, потому что мне никогда не приходилось взаимодействовать с этими файлами во время разработки. Мне стало интересно, и я начала исследовать, из чего состоят эти файлы. Оказалось, что в основном в них находятся функции буферизации PHP (ob_start
, ob_get_contents
).
Давайте представим диалог разработчика с языком программирования PHP (если бы с ним можно было просто поговорить):
Другими словами, PHP отправляет данные в браузер с сервера, как только функция завершается. Например, если вы пишете код: echo "Hi there";
для получения строки «Привет!», она отправляется браузеру сразу после запуска функции с echo
.
Однако, если вы запустите функцию echo
, когда действует буферизация вывода, сообщение «Привет» будет сохранено в этой невидимой удерживающей ячейке, которая и называется буфером. И она не будет отображаться на странице, пока вы не получите ее содержимое и не отправите его в браузер.
Станьте профессиональным PHP-разработчиком с нуля за 10 месяцев На Хекслете есть профессия «PHP-разработчик». Пройдите ее, чтобы изучить один из самых известных языков программирования, освоить популярные фреймворки и создать большое портфолио с проектами на GitHub.
Существует несколько основных функций для работы буферизации вывода php:
ob_start()
запускает буферизацию вывода. Другими словами, она создает буфер (невидимую ячейку), в которой будет храниться весь вывод после ее вызова.
ob_get_contents()
собирает все данные, которые находятся в буфере после выполнения команды ob_start
. Обычно с помощью этой функции данные из буфера присваивают переменной.
ob_clean()
удаляет все из буфера. Обратите внимание, что она ничего не выводит — просто очищает буфер.
ob_flush()
выводит содержимое из буфера. Обратите внимание, что она не очищает буфер.
ob_end_clean()
очищает буфер и отключает буферизацию вывода.
ob_end_flush()
выводит содержимое из буфера и завершает буферизацию вывода. Буфер не стирается.
Самое важное в использовании функций буферизации вывода — это то, где вы их размещаете. Вам нужно запустить буфер с помощью ob_start
в нужном месте, и вывести буфер либо на страницу, либо в переменную, прежде чем вы его очистите.
Возможно вы никогда не будете ее использовать и захотите буферизацию вывода отключить, особенно если вы не являетесь разработчиком плагинов WordPress или не пишете собственные приложения PHP. Для тех, кто не делает ни того, ни другого, я приведу несколько примеров, когда эта концепция все-таки может пригодиться.
Вы когда-нибудь видели такую ошибку?
Warning: Cannot modify header information — headers already sent by (output started at /some/file.php:12) in /some/file.php on line 23
Для тех, кто не знаком с определением HTTP-заголовка — это информация, отправляемая с сервера по HTTP-запросу. Она сообщает браузеру, какие данные передаются, прежде чем попадут к нему.
HTTP-заголовки содержат данные про тип содержимого, дату его последнего изменения, тип отправившего запрос сервера и многое другое. Загвоздка в том, что HTTP-заголовки необходимо отправлять до того, как с сервера будут отправлены какие-либо выходные данные.
И еще один пример: предположим, ваше приложение сохраняет данные для входа пользователя в файлы cookie — в специальный тип HTTP-заголовка. Эти данные должны отправляться в браузер раньше любых других данных сайта или приложения. При этом, в зависимости от того, как устроена ваша программа, код cookie не обязан находиться в самом начале файла.
И тут как раз вступает в действие буферизация вывода, которая позволяет сказать: «Привет, PHP! Я скажу, когда нужно отправить вывод сайта после того, как будут обработаны cookie-файлы». В ином случае вы просто столкнетесь с ошибкой, про которую я писала чуть выше.
Обратите внимание, что появление этой ошибки может указывать и на использование плохих практик написания кода с точки зрения структуры вашего приложения. Например, такая ошибка может выпадать из-за конфликтов с другими плагинами.
При использовании плагинов или фреймворков мы постоянно встречаемся с кодом, про который вообще ничего не знаем — как он работает и даже для чего нужен. Мы просто знаем, как его использовать, и делаем это. Однако иногда все-таки нужно понять, что это за код и зачем он вообще нужен. В случае с буферизацией вывода PHP все точно так же. Сохраните себе эту статью, чтобы вернуться к материалу, если возникнут трудности с буферизацией.
Читайте также: Как работать с базами данных в PHP с помощью модуля PDO