Буферизация контента
Весь 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()
, вы получите мусорный ответ, который сломает ваш <+code>JavaScript.
Метод $APPLICATION->RestartBuffer()
это стандартный и единственно правильный способ решить эту проблему. Он выполняет два действия:
Очищает буфер
вызываетob_end_clean()
, полностью удаляя весь HTML, накопленный с момента подключения прологаПрекращает выполнение
регистрирует функцию, которая вызоветdie()
в конце хита, гарантируя что никакой лишний код не будет выполнен
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();
AJAX-компоненты и буферизация
Когда вы перезагружаете компонент через AJAX runComponentAction
, Битриксу может понадобиться подключить новые CSS или JS файлы, которые используются в шаблоне, просто вернуть HTML будет недостаточно.
Для этого существует метод $APPLICATION->ShowAjaxHead()
. Он возвращает специальные JSON-данные с ассетами. Его нужно вызывать до $APPLICATION->RestartBuffer()
.
// в action-методе компонента (class.php)
public function reloadAction()
{
// логика с кодом
// Готовим ассеты для frontend'а
$this->executeComponent();
global $APPLICATION;
// собираем данные об ассетах
$assetsJs = \Bitrix\Main\Page\Asset::getInstance()->getJs();
$assetsCss = \Bitrix\Main\Page\Asset::getInstance()->getCss();
// и для строк если нужно
// очищаем буфер
$APPLICATION->RestartBuffer();
// одаем JSON, который поймет BX.ajax
header('Content-Type: application/json');
echo json_encode([
// HTML компонента, который был в буфере до очистки
'html' => $this->getTemplateHtml(),
'assets' => [
'js' => $assetsJs,
'css' => $assetsCss,
// и для строк если нужно
]
]);
}