Пользовательский буфер
Работа с буфером вывода начинается с функции ob_start()
включаем буфер вывода используем:
// включаем буфер
ob_start();
// этот, и весь последующий код, будет попадать в буфер вывода
echo "hello world";
Если нужно сохранить данные, или ещё как обработать вывод то нам потребуется функция ob_get_contents()
. Сохранив данные, можно очистить и отключить буфер — для этого воспользуемся функцией ob_end_clean()
:
// включаем буфер
ob_start();
// выводим информацию
echo "hello world";
// сохраняем всё что есть в буфере в переменную $content
$content = ob_get_contents();
// отключаем и очищаем буфер
ob_end_clean();
Функцию ob_get_contents()
можно вызывать множество раз:
// включаем буфер
ob_start();
// выводим информацию
echo "hello ";
// сохраняем всё что есть в буфере в переменную, на данный момент там только `hello`
$a = ob_get_contents();
// выводим информацию
echo "world ";
// повторный вызов, теперь буфер содержит `hello world`
$b = ob_get_contents();
Обработчик буфера
В качестве обработчика буфера в функции ob_start()
, должна быть указана callback-функция, которая принимает содержимое буфера как входной параметр и должна вернуть строку после обработки:
// callback-функция которая возвращает строку
function ob_handler($buffer, $phase)
{
return "Length of string '$buffer' is " . strlen($buffer);
}
// включаем буфер
ob_start('ob_handler');
// выводим информацию
echo "hello world";
// cбрасываем буфер и отправляем его в браузер
ob_end_flush();
Обработка заголовков
Если внутри блока ob_start() – ob_end() вы отправляете заголоввки, например для скачивания файла, заголовок не попадет в буфер, а сразу будет отправлен в браузер и начнется скачивание:
// первый заголовок
header("OB-START: 1");
// включаем буфер
ob_start();
// выводим информацию
echo "hello world";
// сохраняем всё что есть в буфере в переменную, на данный момент там только `hello world`
$a = ob_get_contents();
// второй заголовок
header("PHP-VERSION: " . PHP_VERSION);
// отключаем и очищаем буфер
ob_end_clean();
// третий заголовок
header("OB-END: 1");
В результате выполнения данного кода в http-пакете появятся следующие заголовки:
OB-START: 1
PHP-VERSION: 8.2.19
OB-END: 1
Данное правило по отправке заголовков верно как для непосредственного вызова функции header()
, так и для неявного при вызове session_start()
:
// включаем буфер
ob_start();
// выводим информацию
echo "hello world";
// функция session_start() будет работать корректно
session_start();
// сохраняем всё что есть в буфере в переменную, на данный момент там только `hello world`
$content = ob_get_contents();
// отключаем и очищаем буфер
ob_end_clean();
// выводим информацию
echo "<h1>" . $content . "</h1>";
Теперь в копилке наших знаний есть информация о том, как включить буфер, как получить из него данные, как выключить.
Вложенный буфер
Внутри буфера можно стартовать ещё один буфер, а внутри нового буфера ещё и так далее пока будет хватать памяти сервера:
// уровень 1
echo ob_get_level();
// включаем буфер
ob_start();
// уровень 2
echo ob_get_level();
// включаем буфер
ob_start();
// уровень 3
echo ob_get_level();
// включаем буфер
ob_start();
// уровень 4
echo ob_get_level();
// cбрасываем буфер и отправляем его в браузер
ob_end_flush();
ob_end_flush();
ob_end_flush();
В данном примере функция ob_end_flush()
и производные от неё, будут выбрасывать содержимое буфера на более высокий уровень.
Данный подход поможет в случае, когда вам нужно подключить сторонний код, а он вдруг может что-то взять и вывести — было бы разумно обернуть его вывод в буфер, даже если весь ваш код уже обёрнут в другой буфер.
Если вы не знаете точно на какой глубине находитесь, воспользуйтесь функцией ob_get_level()
в цикле:
while (ob_get_level()) {
ob_end_clean();
}