Ob start: примеры (PHP)

Буферизация вывода в PHP через ob_start
Раздел: Буферизация вывода
ob_start(callable|null $callback = null, int $chunk_size = 0, int $flags = PHP_OUTPUT_HANDLER_STDFLAGS): bool

Основные сведения о функции ob_start

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

Область применения

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

Аргументы функции

Функция принимает три необязательных параметра:

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

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

chunk_size

Устанавливает размер чанка. При достижении указанного размера буфер передается в callback-функцию для обработки.

flags

Битовые флаги, управляющие поведением обработчика. Основные константы: PHP_OUTPUT_HANDLER_STDFLAGS, PHP_OUTPUT_HANDLER_CLEANABLE, PHP_OUTPUT_HANDLER_FLUSHABLE, PHP_OUTPUT_HANDLER_REMOVABLE, PHP_OUTPUT_HANDLER_FINAL.

Простые примеры использования

Базовый пример с захватом вывода

Код:

<?php
ob_start();
echo "Этот текст попадёт в буфер";
$content = ob_get_clean();
echo "Захваченный контент: " . $content;
?>

Результат:

Захваченный контент: Этот текст попадёт в буфер
Использование callback-функции

Код:

<?php
function process_buffer($buffer, $phase) {
    return strtoupper($buffer);
}
ob_start('process_buffer');
echo "текст в нижнем регистре";
ob_end_flush();
?>

Результат:

ТЕКСТ В НИЖНЕМ РЕГИСТРЕ
Работа с флагами

Код:

<?php
ob_start(null, 0, PHP_OUTPUT_HANDLER_CLEANABLE);
echo "Содержимое буфера";
ob_clean(); // Буфер очищается без вывода
?>

Альтернативные функции PHP

ob_get_contents и ob_end_clean

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

output_add_rewrite_var

Функция добавляет переменные перезаписи URL, что полезно для управления сессиями. Работает совместно с буферизацией вывода.

Функции работы с буфером

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

Аналоги в других языках

Python: io.StringIO

Код:

from io import StringIO
import sys
old_stdout = sys.stdout
sys.stdout = buffer = StringIO()
print("Захваченный вывод")
sys.stdout = old_stdout
content = buffer.getvalue()
print(f"Результат: {content}")

Результат:

Результат: Захваченный вывод
JavaScript: перехват console.log

Код:

const originalLog = console.log
let captured = []
console.log = (...args) => {
    captured.push(args.join(' '))
}
console.log('Текст для захвата')
console.log = originalLog
console.log('Захвачено:', captured.join(', '))

Результат в консоли:

Захвачено: Текст для захвата
Java: ByteArrayOutputStream

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

Распространённые ошибки

Невложенность буферов

Код:

<?php
ob_start();
ob_start();
echo "Внутренний буфер";
$inner = ob_get_clean();
echo "Внешний буфер";
$outer = ob_get_clean();
echo $inner . " | " . $outer;
?>

Результат:

Внутренний буфер | Внешний буфер
Попытка очистки несуществующего буфера

Код:

<?php
ob_start();
ob_end_clean();
ob_end_clean(); // Ошибка
?>

Результат:

PHP Notice: ob_end_clean(): failed to delete buffer. No buffer to delete
Использование callback с возвратом нестрокового значения

Код:

<?php
ob_start(function($buffer) {
    return 123; // Должна возвращаться строка
});
echo "тест";
ob_end_flush();
?>

Результат:

PHP Warning: ob_end_flush(): failed to send buffer...

Изменения в новых версиях PHP

PHP 8.0: строгая типизация

Добавлена строгая проверка типов для аргументов функции. Неверные типы теперь вызывают TypeError вместо предупреждений.

PHP 7.3: изменение флагов по умолчанию

Значение по умолчанию для параметра flags изменено с PHP_OUTPUT_HANDLER_STDFLAGS на комбинацию PHP_OUTPUT_HANDLER_CLEANABLE | PHP_OUTPUT_HANDLER_FLUSHABLE | PHP_OUTPUT_HANDLER_REMOVABLE.

PHP 5.4: добавление параметра flags

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

Расширенные примеры

Динамическая минификация HTML

Код:

Пример php
<?php
function minify_html($buffer) {
    $search = ['/\s+/', '/\s*(<|>)\s*/'];
    $replace = [' ', '$1'];
    return preg_replace($search, $replace, $buffer);
}
ob_start('minify_html');
?>
<div>
    <p>   Текст   с   лишними   пробелами   </p>
</div>
<?php ob_end_flush(); ?>

Результат:

<div><p>Текст с лишними пробелами</p></div>
Многоуровневая буферизация с разными обработчиками

Код:

Пример php
<?php
ob_start(function($buffer) {
    return "[Уровень2: $buffer]";
});
echo "Контент";
ob_start(function($buffer) {
    return "{Уровень1: $buffer}";
});
echo "Вложенный";
$inner = ob_get_clean();
echo $inner;
$outer = ob_get_clean();
echo $outer;
?>

Результат:

[Уровень2: {Уровень1: Вложенный}]
Обработка с передачей состояния через замыкание

Код:

Пример php
<?php
$prefix = "Обработано: ";
$callback = function($buffer) use ($prefix) {
    return $prefix . strlen($buffer) . " символов";
};
ob_start($callback);
echo "Пример текста";
ob_end_flush();
?>

Результат:

Обработано: 12 символов
Буферизация с частичной отправкой

Код:

Пример php
<?php
ob_start(null, 10);
for($i = 1; $i <= 25; $i++) {
    echo $i;
    if($i % 10 === 0) ob_flush();
}
ob_end_flush();
?>

Результат с поэтапной отправкой:

12345678910111213141516171819202122232425

PHP ob_start function comments

En
Ob start Turn on output buffering