Блог Горошко Андрея 1C-Битрикс Управление выводом в Битрикс: Буферизация контента и RestartBuffer

Управление выводом в Битрикс: Буферизация контента и RestartBuffer

Средний рейтинг
Еще нет оценок

Весь HTML-код, который генерируется на странице Битрикс, не отправляется в браузер сразу.

Он накапливается в специальном буфере вывода.

Только после того, как отработает эпилог (epilog_after.php), Битрикс выполняет финальные действия (например, заменяет отложенные функции) и отправляет весь накопленный HTML пользователю.

Как и зачем работает буферизация?

В файле /bitrix/modules/main/include/prolog_before.php, который подключается для инициализации ядра, неявно вызывается PHP-функция ob_start().

Она «включает» буферизацию.

Это необходимо для:

  • Отложенных функций: Позволяет в теле страницы вызывать $APPLICATION->SetTitle() или $APPLICATION->AddHeadScript(), а Битрикс вставит результат в <head> в самом конце.
  • События OnEndBufferContent: Дает возможность модулям изменять финальный HTML страницы перед отправкой в браузер.
  • Управления кэшированием.

Проблема: Зачем нужен «чистый» вывод?

Когда вы создаете скрипт для AJAX-запроса или для генерации файла (PDF, CSV), вам не нужен стандартный HTML-шаблон сайта.

Вам нужен «чистый» ответ — только JSON-строка или бинарное содержимое файла.

Если в AJAX-скрипте просто написать echo json_encode(…), вы получите «мусорный» ответ, который сломает ваш JavaScript:

<!DOCTYPE html>...
<head>...</head>
<body>
...
{"status":"success","data":"my_data"}  <!-- <- Только эта часть вам нужна -->
...
</body>
</html>

Решение: $APPLICATION->RestartBuffer()

Метод $APPLICATION->RestartBuffer() — это стандартный и единственно правильный способ решить эту проблему. Он выполняет два действия:

  1. Очищает буфер: Вызывает ob_end_clean(), полностью удаляя весь HTML, накопленный с момента подключения пролога.
  2. Прекращает выполнение: Регистрирует функцию, которая вызовет die() в конце хита, гарантируя, что никакой лишний код (например, эпилог) не будет выполнен.

Практический пример 1: AJAX-обработчик

Создадим файл /ajax/get_time.php, который будет возвращать текущее время в формате JSON.

// /ajax/get_time.php

// Подключаем ядро для доступа к API Битрикс
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

// Проверяем права, сессию, входные данные...
if (!check_bitrix_sessid() || !$USER->IsAuthorized()) {
    // В этом случае можно не очищать буфер, а просто завершить работу.
    // Битрикс вернет стандартный HTML-ответ с ошибкой доступа.
    return;
}

global $APPLICATION;
$APPLICATION->RestartBuffer(); // <-- Ключевой момент! Очищаем всё, что вывел пролог.

$data = [
    'time' => (new \Bitrix\Main\Type\DateTime())->format('H:i:s'),
    'status' => 'ok'
];

// Устанавливаем правильный заголовок для JSON
header('Content-Type: application/json');

// Выводим ТОЛЬКО наши данные
echo json_encode($data);

// Явно вызывать die() не нужно, RestartBuffer сделает это за нас.

Практический пример 2: Генерация CSV-файла

Логика абсолютно та же: подключить ядро, выполнить логику, очистить буфер и вывести содержимое файла.

// /admin/tools/export_users.php
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

global $APPLICATION, $USER;
if (!$USER->IsAdmin()) return;

$APPLICATION->RestartBuffer();

// Заголовки для скачивания файла
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="users.csv"');

$output = fopen('php://output', 'w');
fputcsv($output, ['ID', 'LOGIN', 'EMAIL'], ';'); // Заголовки CSV

$rsUsers = CUser::GetList($by='id', $order='asc', ['ACTIVE' => 'Y']);
while($arUser = $rsUsers->Fetch()) {
    fputcsv($output, [$arUser['ID'], $arUser['LOGIN'], $arUser['EMAIL']], ';');
}

// die() не нужен

RestartBuffer vs. die() — В чем разница?

КодРезультат
echo ‘A’; die();В браузер отправится весь накопленный буфер (включая HTML из header.php) + символ ‘A’.
echo ‘A’; RestartBuffer();Буфер будет очищен, die() будет вызван позже. В итоге ответ будет пустым, так как ‘A’ было выведено до очистки.
RestartBuffer(); echo ‘A’;Буфер очищен, затем в него помещается ‘A’. В конце хита ‘A’ отправляется в браузер. Это правильный порядок.

Важный нюанс для AJAX-компонентов: ShowAjaxHead()

Когда вы перезагружаете компонент через AJAX (runComponentAction), Битриксу может понадобиться подключить новые CSS или JS файлы, которые используются в шаблоне. Просто вернуть HTML будет недостаточно.

Для этого существует метод $APPLICATION->ShowAjaxHead(). Он возвращает специальные JSON-данные с ассетами. Его нужно вызывать до RestartBuffer.

// В action-методе компонента (class.php)
public function reloadAction()
{
    // ... логика ...

    // Готовим ассеты для frontend'а
    $this->executeComponent();
    
    global $APPLICATION;
    
    // Собираем данные об ассетах
    $assets = \Bitrix\Main\Page\Asset::getInstance()->getJs();
    // ... и для CSS, и для строк
    
    // Очищаем буфер
    $APPLICATION->RestartBuffer();

    // Отдаем JSON, который поймет BX.ajax
    header('Content-Type: application/json');
    echo json_encode([
        'html' => $this->getTemplateHtml(), // HTML компонента, который был в буфере до очистки
        'assets' => [
            'js' => $assets,
            // ...
        ]
    ]);
    
    // ...
}

Вывод:
$APPLICATION->RestartBuffer() — это обязательный инструмент для создания «чистых» ответов в AJAX-скриптах и генераторах файлов, которым нужен доступ к API Битрикс.

Всегда используйте его после всех проверок и до вывода основного контента.

Это гарантирует, что ваш frontend получит именно те данные, которые ожидает, без лишнего HTML-кода.

буферизация Битрикс, RestartBuffer, $APPLICATION, ShowAjaxHead, AJAX, JSON, очистка буфера, prolog_before, генерация файлов.

Мой рейтинг:

Добавить комментарий

Related Post

Bitrix D7 ORM: Мастер-класс по ElementTable::getList для выборки элементовBitrix D7 ORM: Мастер-класс по ElementTable::getList для выборки элементов

Средний рейтинг 5 из 5 звезд. 1 голосов. С появлением ядра D7 в 1С-Битрикс у разработчиков появился новый, объектно-ориентированный способ работы с базой данных — ORM (Object-Relational Mapping). Этот подход

 Ядро D7: Application, Context и Request — современная работа с окружением Ядро D7: Application, Context и Request — современная работа с окружением

Средний рейтинг Еще нет оценок В старом ядре Битрикс для доступа к данным окружения использовались глобальные переменные ($APPLICATION, $_SERVER, $_POST, $_SESSION). Этот подход затрудняет тестирование и понимание кода. В ядре D7 введены специальные

Работа с Highload-блоками в Битрикс через D7 ORM: Пошаговое руководствоРабота с Highload-блоками в Битрикс через D7 ORM: Пошаговое руководство

Средний рейтинг Еще нет оценок Highload-блоки (HL-блоки) — это мощный инструмент 1С-Битрикс для хранения произвольных структурированных данных, не являющихся контентом в классическом понимании (как, например, новости или товары). Это могут