index.php в Bitrix: варианты применения и нестандартные решения

Раздел: Разработка на PHP -> Разработка на Bitrix

Файл index.php в Bitrix: варианты использования и кастомизация

Файл index.php в корне сайта на 1С-Битрикс является точкой входа для всех HTTP-запросов, если не настроены дополнительные правила модуля "Управление структурой" (ЧПУ). В большинстве случаев разработчики используют стандартный файл, поставляемый с системой, но существуют сценарии, когда требуется изменить его поведение. Рассмотрим различные подходы, начиная с базового и заканчивая продвинутыми вариантами.

Основное решение: стандартный index.php от 1С-Битрикс

Стандартный файл выполняет последовательность обязательных действий: подключает пролог, определяет текущую страницу, проверяет права доступа, подключает компоненты, выводит буферизованный контент, подключает эпилог. Этот вариант подходит для 95% проектов.

<?php
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

// Определение и выполнение действия страницы
$APPLICATION->IncludeComponent("bitrix:main.include", "", ["AREA_FILE_SHOW" => "file", "PATH" => "/include/header.php"]);

$APPLICATION->ShowHead();
?><!DOCTYPE html>
<html>
<head>
<?php $APPLICATION->ShowHead(); ?>
</head>
<body>
<?php $APPLICATION->ShowPanel(); ?>
<?php
$APPLICATION->IncludeComponent("bitrix:breadcrumb", "", []);
?>
<h1>Заголовок</h1>
<?php
$APPLICATION->IncludeComponent("bitrix:news.list", "", ["IBLOCK_ID" => 1, "NEWS_COUNT" => 5]);
?>
<?php
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");
?>
</body>
</html>

файл index php bitrix (файл index.php в bitrix)

Пояснение: prolog_before.php инициализирует ядро, сессию, авторизацию. ShowHead() выводит мета-теги, заголовок. ShowPanel() - административную панель. Путь к footer.php завершает буферизацию и выводит контент.

Типичная ошибка: дублирование вывода head-тегов.

Если дважды вызвать $APPLICATION->ShowHead(), браузер увидит повторяющиеся теги, что может нарушить валидацию. Решение: вызывать функцию только один раз, перед закрытием </head>.

Как настроить index.php для работы с произвольной структурой URL?

Стандартный файл обрабатывает страницы через компонент bitrix:system.pagenavigation и протокол ЧПУ. Если необходимо перехватить запрос до запуска компонентов, используется механизм событий или изменение файла.

<?php
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

// Перехват запроса и перенаправление на другой URL
if (strpos($_SERVER["REQUEST_URI"], "/old/") === 0) {
    LocalRedirect("/new/", true);
}

// Далее стандартный код...
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_after.php");
?>

Проблема: редирект до пролога после может вызвать ошибку с сессией.

Используйте LocalRedirect() только после инициализации ядра, но до начала вывода контента. Вызов до prolog_before.php приведёт к фатальной ошибке.

Как подключить свой обработчик событий на каждой странице?

Вместо правки index.php можно использовать обработчик события OnBeforeProlog. Это предпочтительнее, так как не требует изменения файла при обновлении системы.

// В init.php или пользовательском модуле
AddEventHandler("main", "OnBeforeProlog", "myBeforePrologHandler");
function myBeforePrologHandler() {
    if ( CSite::InDir("/catalog/") ) {
        // Действия для раздела каталога
    }
}

Ошибка: обработчик выполняется даже для AJAX-запросов.

Проверяйте $_SERVER['HTTP_BX_AJAX'] или константу BX_AJAX, чтобы не выполнять лишние действия.

Как организовать многоязычность через index.php?

Можно определить язык сайта на основе домена или префикса URL и подключить соответствующую версию сайта.

<?php
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

$lang = substr($_SERVER["HTTP_HOST"], 0, 2); // en.mysite.ru, de.mysite.ru
$siteId = ($lang === "en") ? "s1" : (($lang === "de") ? "s2" : "s1");
CHTTP::SetStatus("200 OK");
$_SERVER["HTTP_HOST"] = $siteId; // Изменение для компонентов
$GLOBALS["SITE_ID"] = $siteId;
// Далее стандартный пролог...
?>

Проблема: компоненты кешируют по SITE_ID, и переопределение может привести к неправильным данным.

Используйте механизм языковых версий через настройки сайта в админке, а не переопределение глобальной переменной.

Расширенный вариант: использование index.php для PWA или SPA

Для одностраничных приложений на Bitrix можно сделать index.php минимальным, передавая всю логику на фронтенд через REST API. В этом случае файл служит только для инициализации ядра и загрузки одного шаблона.

<?php
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

// Отключаем вывод компонентов, передаём пустой див для Vue/React
$APPLICATION->ShowHead();
?><!DOCTYPE html>
<html><head><?php $APPLICATION->ShowHead(); ?></head>
<body>
<div id="app"></div>
<script src="/local/js/app.js"></script>
</body></html>
<?php
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");
?>

Ошибка: при таком подходе пропадает встроенный функционал SEO (хлебные крошки, мета-теги).

Нужно реализовать их на стороне фронтенда через API или оставить минимальную серверную разметку.

Продвинутые примеры модификации index.php

Пример 1: Автоматическое определение шаблона сайта в зависимости от поддомена

Пример
<?php
// index.php для многосайтовости на одном физическом хосте
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

$host = $_SERVER["HTTP_HOST"];
$siteMap = [
    'shop.mysite.ru' => 's1',
    'blog.mysite.ru' => 's2',
];
if (array_key_exists($host, $siteMap)) {
    $siteId = $siteMap[$host];
    COption::SetOptionString("main", "site_id", $siteId, false, $siteId);
    $GLOBALS['SITE_ID'] = $siteId;
}

// Стандартный код...
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_after.php");
?>

Результат:

При переходе на shop.mysite.ru загружается шаблон интернет-магазина, на blog.mysite.ru – шаблон блога.

Важно: после изменения SITE_ID необходимо очистить кеш компонентов, иначе старые данные могут остаться.

Пример 2: Запись в лог всех запросов к сайту

Пример
<?php
// Разместить в начале index.php до подключения пролога
$logDir = $_SERVER["DOCUMENT_ROOT"] . "/local/logs/";
if (!is_dir($logDir)) {
    mkdir($logDir, 0755, true);
}
file_put_contents($logDir . "requests.log", 
    date("Y-m-d H:i:s") . " " . $_SERVER['REQUEST_URI'] . " " . $_SERVER['REMOTE_ADDR'] . "\n", 
    FILE_APPEND
);
?>
Файл requests.log заполняется записями вида: 2025-03-30 14:22:10 /catalog/product/ 192.168.1.1

Примечание:

Такой подход может вызвать проблемы производительности на высоконагруженных проектах. Рекомендуется использовать асинхронную запись или модуль CEventLog.

Пример 3: Динамическое подключение сервис-воркера для PWA

Пример
<?php
// В index.php после prolog_before
if (isset($_SERVER['HTTP_SERVICE_WORKER_ALLOWED']) && $_SERVER['HTTP_SERVICE_WORKER_ALLOWED'] === 'true') {
    header('Service-Worker-Allowed: /');
}
?>
Браузер получает заголовок, разрешающий регистрацию service-worker из корня сайта.

Обычно этого можно достичь через файл .htaccess или web.config, но данный пример показывает возможность гибкой настройки через PHP.

Пример 4: Выполнение кода только для определённой группы пользователей

Пример
<?php
// После инициализации сессии
$user = CUser::GetByID($USER->GetID());
if ($arUser = $user->Fetch()) {
    if (in_array(7, $arUser['GROUP_ID'])) { // группа id=7 – менеджеры
        $APPLICATION->IncludeComponent("bitrix:infoblock", "", ["IBLOCK_ID" => 10]);
    }
}
?>
Менеджеры видят дополнительный блок с информацией, остальные – нет.

Проблема:

Если компонент включён в кешируемый шаблон, кеш будет отличаться для разных групп. Необходимо использовать динамические компоненты (ajax или bitrix:main.include с параметром CACHE_TYPE = "N").

Пример 5: Принудительное использование HTTPS через index.php

Пример
<?php
// Перед prolog_before
if ($_SERVER['HTTPS'] !== 'on' && $_SERVER['HTTP_X_FORWARDED_PROTO'] !== 'https') {
    $redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    header('HTTP/1.1 301 Moved Permanently');
    header('Location: ' . $redirect);
    exit();
}
?>
Посетители автоматически перенаправляются на HTTPS-версию страницы.

Этот код должен быть самым первым в файле, до любых выводов данных. В противном случае произойдет ошибка "headers already sent".

Пример 6: Предзагрузка данных из кеша для ускорения работы

Пример
<?php
// Перед прорисовкой компонента
$cache = new CPHPCache();
$cacheTime = 3600*24; // 24 часа
$cacheId = "main_page_data";
$cachePath = "/main/";
if ($cache->InitCache($cacheTime, $cacheId, $cachePath)) {
    $vars = $cache->GetVars();
} else {
    $vars = [
        'news' => getNewsData(),
        'banners' => getBannersData(),
    ];
    if ($cache->StartDataCache()) {
        $cache->EndDataCache($vars);
    }
}
// Использование $vars в шаблоне...
?>
Сложные запросы выполняются один раз в сутки, сокращая время генерации страницы.

При кешировании важно учитывать очистку при изменении данных. Используйте тегированные кеши или события очистки.

Файл index.php в Bitrix - comments

En
файл index php bitrix (php)