W3docs

Функция PHP ob_start(): всё, что нужно знать

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

Когда PHP выполняет скрипт, каждый вызов echo, print или блок HTML обычно сразу же отправляется клиенту. Буферизация вывода меняет это поведение: она удерживает всё, что скрипт должен вывести, в буфере в памяти, чтобы вы могли захватить, изменить или отбросить данные до того, как они покинут сервер. Функция ob_start() — это встроенная функция, которая включает такую буферизацию.

В этой главе объясняется, что делает ob_start(), её параметры, как захватывать и преобразовывать вывод, наиболее распространённые реальные сценарии использования и типичные ошибки.

Что такое функция ob_start()?

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

Буферизация не задерживает HTTP-заголовки. Поскольку тело ответа больше не отправляется сразу, вы всё ещё можете вызывать такие функции, как header(), после того как уже выводили данные через echo — это единственная наиболее распространённая причина, по которой разработчики прибегают к ob_start().

Буферы также вкладываются: каждый вызов ob_start() добавляет новый буфер в стек, а соответствующая функция закрытия/сброса извлекает верхний. Вы можете узнать глубину стека с помощью ob_get_level().

Синтаксис

ob_start(
    ?callable $callback = null,
    int $chunk_size = 0,
    int $flags = PHP_OUTPUT_HANDLER_STDFLAGS
): bool

Параметры:

  • $callback — Необязательный. Функция, которая получает содержимое буфера (и битовую маску состояния) и возвращает строку для фактического вывода. Используйте её для преобразования всего, что выводит скрипт, — например, для минификации HTML или его gzip-сжатия.
  • $chunk_size — Необязательный. Если больше 0, обратный вызов выполняется каждый раз, когда буфер достигает указанного размера в байтах, а не только при сбросе буфера. 0 (по умолчанию) означает сброс только при завершении.
  • $flags — Необязательный. Битовая маска, определяющая, можно ли очищать, сбрасывать и удалять буфер. Значение по умолчанию PHP_OUTPUT_HANDLER_STDFLAGS разрешает все три операции.

Возвращаемое значение: true при успехе, false при неудаче.

Базовое использование: захват вывода

Наиболее распространённый паттерн — начать буфер, вывести что-нибудь, затем захватить это в переменную с помощью ob_get_clean() (которая за один шаг возвращает буфер и отключает буферизацию):

<?php

ob_start();                 // start buffering — nothing is sent yet
echo "Hello, ";
echo "world!";
$output = ob_get_clean();   // grab the buffer as a string, stop buffering

echo strtoupper($output);   // now we control what actually gets sent

Вывод:

HELLO, WORLD!

Здесь два вызова echo никогда не достигают клиента напрямую. ob_get_clean() возвращает "Hello, world!", и в итоге выводится только версия в верхнем регистре. Этот поток «захват — преобразование» и делает буферизацию мощным инструментом.

Преобразование вывода с помощью обратного вызова

Вместо ручного захвата вы можете передать обратный вызов в ob_start(). PHP автоматически запустит его над буфером при его сбросе (здесь — в конце скрипта):

<?php

function addBang(string $buffer): string
{
    return str_replace("world", "World!", $buffer);
}

ob_start("addBang");
echo "hello world";
// buffer is flushed automatically at script end → callback runs

Вывод:

hello World!

Именно так работают встроенные обработчики, например ob_gzhandler() — передайте его в качестве обратного вызова, и вся страница будет прозрачно сжата gzip.

Распространённые сценарии использования

  • Отправка заголовков после вывода. Поскольку тело ответа буферизуется, вы всё ещё можете вызывать header() или setcookie() после вывода HTML, избегая ошибки «headers already sent». См. headers_sent().
  • Шаблонизация. Захватывайте отрендеренный HTML файла шаблона в строку вместо его прямого вывода, чтобы его можно было вернуть, кешировать или обернуть в макет.
  • Постобработка всей страницы. Минифицируйте HTML, переписывайте URL или удаляйте комментарии через обратный вызов перед отправкой.
  • Сжатие. Используйте ob_gzhandler для сжатия ответов без изменения вызовов echo в скрипте.

Связанные функции

ob_start() редко используется в одиночку. Эти функции управляют созданным ею буфером:

  • ob_get_contents() — Возвращает содержимое буфера без его очистки.
  • ob_get_clean() — Возвращает буфер и отключает буферизацию.
  • ob_clean() — Отбрасывает содержимое буфера, но оставляет буферизацию включённой.
  • ob_end_flush() — Отправляет буфер клиенту и отключает буферизацию.
  • ob_end_clean() — Отбрасывает буфер и отключает буферизацию (ничего не отправляет).
  • ob_get_level() — Возвращает количество текущих вложенных буферов.

Более широкий обзор см. в разделе PHP Output Control.

Типичные ошибки

  • Всегда закрывайте то, что открыли. Каждый ob_start() должен быть сопоставлен с вызовом flush/clean. Незакрытый буфер автоматически сбрасывается в конце скрипта, но незакрытые буферы в длинных скриптах могут скрывать вывод или тратить память.
  • ob_get_clean() возвращает false, если буфер не активен. Вызов без соответствующего ob_start() даёт false, а не пустую строку.
  • Буферизация ≠ бесконечные заголовки. Сами заголовки не буферизуются; буферизуется только тело. Как только любой буфер сброшен клиенту, заголовки зафиксированы.

Заключение

ob_start() включает буферизацию вывода, чтобы PHP удерживал вывод скрипта в памяти вместо немедленной отправки. Это позволяет захватывать вывод в строку, преобразовывать его с помощью обратного вызова, отправлять заголовки после вывода или сжимать всю страницу. Используйте её вместе с ob_get_clean() для захвата, ob_end_flush() для отправки и ob_end_clean() для отбрасывания — и помните, что нужно всегда закрывать каждый открытый буфер.

Практика

Практика
Что делает функция 'ob_start()' в PHP?
Что делает функция 'ob_start()' в PHP?
Was this page helpful?