Стандарты кода 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. Защита файла от прямого вызова
<?phpif (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();Это первая строка каждого PHP-файла компонента, шаблона и обработчика. Без неё файл можно выполнить напрямую по URL, минуя ядро, права доступа и всю логику приложения.
2. Языковые файлы
$MESS['MYMODULE_NEWS_LIST_EMPTY'] = 'Новостей пока нет';$MESS['MYMODULE_NEWS_LIST_ERROR'] = 'Не удалось загрузить новости';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/ и публичную часть сайта.
Связанные темы
- Архитектура платформы - почему код живёт в /local/
- Composer и автозагрузка - второй автозагрузчик классов рядом со штатным Loader
- Компоненты 2.0 - разделение логики и шаблона
- Безопасность - экранирование при выводе
- Раздел Основы
- Git и выкладка проекта: что версионировать и как переносить - работа с репозиторием