В многосайтовой установке 1С-Битрикс нередко возникает ситуация, когда один из сайтов уже создан, но ещё находится в разработке. При этом остальные сайты той же установки должны продолжать работать в обычном режиме.
Например, имеется одна установка Битрикс с несколькими сайтами:
s1 — основной действующий сайт
s2 — новый сайт в разработке
s3 — ещё один действующий сайтДля нового сайта необходимо временно показывать посетителям страницу-заглушку, но при этом администратор должен иметь возможность видеть настоящий сайт и продолжать его настройку.
На первый взгляд задача простая: определить текущий сайт и завершить выполнение страницы через die(). Однако в многосайтовой установке необходимо учитывать выполнение cron и агентов Битрикс.
Почему обычная заглушка может создать проблему
Один из распространённых вариантов закрытия сайта заключается в использовании события OnBeforeProlog.
Например:
<?php
AddEventHandler("main", "OnBeforeProlog", "MyOnBeforePrologHandler", 50);
function MyOnBeforePrologHandler()
{
global $USER;
if (!is_object($USER)) {
$USER = new CUser();
}
if (!$USER->IsAdmin()) {
include($_SERVER["DOCUMENT_ROOT"] . "/coming-soon/underconstruction.html");
die();
}
}Такой код действительно закрывает сайт для обычных пользователей и оставляет его доступным администраторам.
Проблема заключается в строке:
die();Если такой обработчик будет выполнен во время запуска cron, PHP-процесс завершится до того, как Битрикс успеет выполнить необходимые задания.
Почему это особенно важно в многосайтовости
При классической многосайтовости сайты используют одну установку Битрикс, общее ядро и общую базу данных.
Например:
Одна установка Битрикс
s1 — основной сайт
s2 — новый сайт
s3 — дополнительный сайт
Общие:
/bitrix
/local
/upload
база данныхАгенты также находятся в общей базе данных. Это не три полностью независимые очереди заданий вида:
cron сайта s1
cron сайта s2
cron сайта s3Фактически cron запускает общий механизм Битрикс, который затем выполняет необходимые агенты.
Поэтому если во время такого запуска сработает обработчик с die(), проблема потенциально касается не только закрытого сайта, но и выполнения заданий всей установки.
Как правильно закрыть только один сайт
Удобный вариант — разместить обработчик именно в файле init.php нужного сайта.
Например, если закрывается сайт с идентификатором s2, используется файл:
/local/php_interface/s2/init.phpТаким образом логика заглушки относится именно к этому сайту.
При этом желательно дополнительно исключить выполнение обработчика в режиме cron и при запуске PHP из командной строки.
Готовый вариант кода
<?php
AddEventHandler(
'main',
'OnBeforeProlog',
'closeS2ForVisitors',
50
);
function closeS2ForVisitors()
{
/*
* Не закрываем сайт при выполнении cron
* и других PHP-скриптов из командной строки.
*/
if (
(defined('BX_CRONTAB') && BX_CRONTAB === true)
|| PHP_SAPI === 'cli'
) {
return;
}
global $USER;
if (!is_object($USER)) {
$USER = new CUser();
}
/*
* Администратор видит обычный сайт.
*/
if ($USER->IsAdmin()) {
return;
}
/*
* Для остальных посетителей выводим заглушку.
*/
include $_SERVER['DOCUMENT_ROOT']
. '/coming-soon/underconstruction.html';
die();
}Что делает этот код
Обработчик подключается к событию OnBeforeProlog, которое выполняется на раннем этапе загрузки страницы.
Сначала выполняется проверка:
if (
(defined('BX_CRONTAB') && BX_CRONTAB === true)
|| PHP_SAPI === 'cli'
) {
return;
}Если Битрикс работает в режиме cron либо PHP был запущен через командную строку, обработчик сразу прекращает свою работу и никак не мешает дальнейшему выполнению скрипта.
Затем проверяется текущий пользователь:
if ($USER->IsAdmin()) {
return;
}Если пользователь является администратором, сайт открывается в обычном режиме.
Для остальных посетителей подключается файл заглушки:
include $_SERVER['DOCUMENT_ROOT']
. '/coming-soon/underconstruction.html';
die();Где разместить страницу-заглушку
Например, можно создать каталог:
/coming-soon/и файл:
/coming-soon/underconstruction.htmlПростейшее содержимое страницы:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сайт находится в разработке</title>
</head>
<body>
<h1>Сайт находится в разработке</h1>
<p>
Мы готовим новый сайт. Пожалуйста, зайдите немного позже.
</p>
</body>
</html>Почему дополнительно проверяется PHP_SAPI
Константа BX_CRONTAB используется Битрикс при штатном запуске заданий cron.
Однако на сервере могут существовать и собственные CLI-скрипты, например:
php /home/site/scripts/import.php
php /home/site/scripts/update_catalog.php
php /home/site/scripts/sync.php
Для них константа BX_CRONTAB может отсутствовать.
Проверка:
PHP_SAPI === 'cli'позволяет не применять заглушку ко всем PHP-скриптам, запущенным через командную строку.
Почему лучше использовать отдельный init.php сайта
В многосайтовой установке существует общий файл:
/local/php_interface/init.phpКод из него относится ко всей установке.
Кроме него можно использовать отдельные файлы для конкретных сайтов:
/local/php_interface/s1/init.php
/local/php_interface/s2/init.php
/local/php_interface/s3/init.php
Если необходимо временно закрыть только s2, логичнее размещать соответствующий обработчик именно здесь:
/local/php_interface/s2/init.php
Это позволяет не добавлять в общий init.php дополнительные условия вроде:
if (SITE_ID === 's2') {
...
}И одновременно уменьшает риск случайно повлиять на остальные сайты установки.
Как проверить работу
После добавления обработчика необходимо проверить несколько сценариев.
1. Открытие сайта без авторизации
Откройте новый сайт в другом браузере или режиме инкогнито.
Должна отображаться страница:
Сайт находится в разработке2. Открытие сайта администратором
Авторизуйтесь в Битрикс как администратор и откройте тот же домен.
Должен отображаться настоящий сайт со всеми компонентами и шаблоном.
3. Проверка остальных сайтов
Откройте s1, s3 и остальные сайты установки.
Их работа не должна измениться.
4. Проверка cron
Если агенты переведены на cron, после установки заглушки необходимо убедиться, что задания продолжают выполняться.
Особенно это касается:
- отправки почты;
- импорта и экспорта;
- обмена с 1С;
- переиндексации;
- обработки заказов;
- автоматической синхронизации;
- собственных агентов проекта.
Что не рекомендуется делать
Не стоит размещать в общем /local/php_interface/init.php безусловный код:
include '/path/to/underconstruction.html';
die();Такой код потенциально может завершить любой процесс, в котором загружается пролог Битрикс.
Также нежелательно закрывать сайт только через проверку администратора:
if (!$USER->IsAdmin()) {
die();
}Поскольку cron и системные CLI-скрипты обычно не являются авторизованными пользователями сайта и также могут попасть под такое условие.
Итог
В многосайтовой установке 1С-Битрикс один из сайтов можно безопасно закрыть на время разработки с помощью обработчика OnBeforeProlog.
Лучше всего размещать обработчик в отдельном файле:
/local/php_interface/ID_САЙТА/init.phpНапример:
/local/php_interface/s2/init.phpПри этом обязательно следует исключить выполнение заглушки для cron и CLI:
if (
(defined('BX_CRONTAB') && BX_CRONTAB === true)
|| PHP_SAPI === 'cli'
) {
return;
}В результате обычные посетители видят страницу «Сайт находится в разработке», администратор продолжает работать с настоящим сайтом, остальные сайты многосайтовой установки остаются доступными, а системные задания и агенты продолжают выполняться.

После установки заглушки стоит проверить не только сайт в обычном браузере, но и запуск cron из командной строки. В многосайтовой установке одно преждевременное die() в общем обработчике способно оборвать процесс до выполнения агентов, поэтому разделение логики по init.php сайтов и исключение CLI нужно тестировать вместе. Это особенно важно при техническом сопровождении сайта на 1С-Битрикс.


