Перейти к содержимому

Стандарты кода 1С-Битрикс - оформление, именование, языковые файлы

В 1С-Битрикс действуют два параллельных свода правил: формальное оформление кода и архитектурные соглашения о том, где этот код живёт. Второе важнее: нарушение оформления портит читаемость, а нарушение архитектурных правил ломает обновляемость проекта.

Как это работает

Оформление. Отступы табами, кодировка UTF-8, переводы строк LF, длина строки до 120 символов, имена тегов, атрибутов и CSS-классов в нижнем регистре, чёткое разделение HTML как структуры, CSS как представления и JS как поведения.

Архитектурные соглашения. Весь кастомный код - в /local/, файлы ядра не редактируются. Классы - в пространствах имён в верхнем верблюжьем регистре, в папке lib модуля. Тексты - в языковых файлах. Логика отделена от представления: никакого HTML внутри PHP-логики, никакого прямого SQL, никакой бизнес-логики в шаблоне.

Отношение к PSR - выборочное. Ядро D7 использует часть стандартов как контракты интеграции: PSR-4 для автозагрузки (как она уживается со штатным Bitrix\Main\Loader - в статье «Composer и автозагрузка»), PSR-3 для логгеров, PSR-11 для контейнера сервисов, PSR-16 для хранилища, PSR-18 для HTTP-клиента. Но PSR-12 буквально не соблюдается: отступы табами, а не пробелами, ключи массивов данных традиционно в верхнем регистре, открывающая фигурная скобка класса и метода - с новой строки. Не переформатируйте код платформы «под PSR-12» автоматически.

Языковые файлы. Все видимые пользователю тексты выносятся в файлы lang/<язык>/<имя>.php, где заполняется массив $MESS. Система сливает все такие массивы в один, поэтому коды фраз обязаны быть уникальными в пределах продукта.

Примеры

1. Защита файла от прямого вызова

<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();

Это первая строка каждого PHP-файла компонента, шаблона и обработчика. Без неё файл можно выполнить напрямую по URL, минуя ядро, права доступа и всю логику приложения.

2. Языковые файлы

lang/ru/class.php
$MESS['MYMODULE_NEWS_LIST_EMPTY'] = 'Новостей пока нет';
$MESS['MYMODULE_NEWS_LIST_ERROR'] = 'Не удалось загрузить новости';
class.php
use Bitrix\Main\Localization\Loc;
Loc::loadMessages(__FILE__);
echo Loc::getMessage('MYMODULE_NEWS_LIST_EMPTY');

Два правила, которые предотвращают самые частые проблемы. Первое: код фразы начинается с префикса модуля или компонента - иначе при совпадении с чужим кодом победит последний подключённый файл, и текст «уедет» в неожиданном месте. Второе: имя языкового файла должно совпадать с именем основного PHP-файла, иначе отложенная загрузка не сработает.

В файле component_epilog.php автозагрузки фраз нет вообще - там нужен явный вызов Loc::loadLanguageFile(__FILE__), иначе вместо текста увидите коды.

3. Логика отдельно от вывода

// class.php - готовим данные
$this->arResult['ITEMS'] = $this->loadItems();
// template.php - только выводим
<?php foreach ($arResult['ITEMS'] as $item): ?>
<div class="news-item">
<?= htmlspecialcharsbx($item['NAME']) ?>
</div>
<?php endforeach; ?>

В шаблоне не должно быть запросов к базе, обращений к API и бизнес-логики. Обратная ошибка тоже распространена: HTML внутри класса компонента. И помните про экранирование - массив результата автоматически не фильтруется.

4. Структура своего кода

/local/components/mycompany/news.list/ - компонент в своём пространстве имён
/local/modules/mycompany.crm/lib/ - классы модуля
/local/templates/main/ - шаблон сайта
/local/php_interface/init.php - обработчики
/local/js/mycompany/widget/ - JS-расширение

Собственные компоненты и модули кладут в своё пространство имён, а не в bitrix. Системные шаблоны перед правкой копируют в шаблон сайта.

Справочник соглашений

ОбластьСоглашение
Отступытабы, длина строки до 120 символов
Кодировка и переводы строкUTF-8, LF
Классы и пространства имёнверхний верблюжий регистр, файлы в lib модуля
Методы и переменныенижний верблюжий регистр
Ключи массивов данныхтрадиционно верхний регистр
Фигурная скобка класса и методас новой строки
Теги, атрибуты, CSS-классынижний регистр
Свой кодтолько в /local/
Файлы ядране редактируются никогда
Тексты интерфейсав языковых файлах, коды с префиксом
Первая строка PHP-файла компонентазащита от прямого вызова
ДокументированиеPHPDoc для классов и методов, docblock в шаблонах

Частые ошибки

Автоформатирование «под PSR-12». Ломает единообразие с кодом платформы и раздувает историю изменений. Настройте IDE на табы и границу в 120 символов.

Совпадение кодов языковых фраз. Все файлы сливаются в один массив, побеждает последний подключённый. Префикс модуля в коде фразы решает проблему.

Фразы в эпилоге компонента выводятся кодами. В component_epilog.php нет автоматической подгрузки языкового файла.

Заголовок из result_modifier.php пропадает на закешированных страницах. Этот файл выполняется только перед шаблоном, а при валидном кеше шаблон не подключается. Такие вещи задают в классе компонента или в эпилоге.

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

Визуальные щели между блоками. Переводы строк в разметке рендерятся как пробел между строчно-блочными элементами. Убираются комментарием между тегами.

Частые вопросы

Битрикс следует PSR?

Частично и осознанно. Как контракты интеграции используются PSR-4 для автозагрузки, PSR-3 для логгеров, PSR-11 для контейнера сервисов, PSR-16 для хранилища и PSR-18 для HTTP-клиента. А вот PSR-12 буквально не соблюдается: отступы табами, ключи массивов данных в верхнем регистре, скобка класса с новой строки. В своём коде разумно следовать стилю платформы - так проще читать и ядро, и собственные модули.

Почему нельзя править файлы в /bitrix/?

По трём причинам сразу: правки затрутся ближайшим обновлением, проект теряет право на техподдержку, и модифицированное ядро может повести себя непредсказуемо. Всё, что нужно изменить, делается через /local/: переопределение компонентов и шаблонов, события, наследование классов, контейнер сервисов.

Как правильно называть коды языковых фраз?

С уникальным префиксом - обычно это имя модуля или компонента, например MYMODULE_NEWS_LIST_EMPTY. Система сливает все языковые массивы в один, поэтому короткий код вроде TITLE рано или поздно столкнётся с чужим, и в каком-то месте сайта появится посторонний текст. Имя самого языкового файла должно совпадать с именем PHP-файла, к которому он относится.

Что не должно попадать в репозиторий?

Ядро и загруженные файлы: папки /bitrix/ и /upload/ в git обычно не хранят - они большие и обновляются платформой. Также не место в репозитории кешу, логам, локальным настройкам подключения к базе и любым секретам. Версионируют то, что пишете вы: /local/ и публичную часть сайта.

Связанные темы

Первоисточники