Рефакторинг коду проекту на 1С-Бітріксі
Аудит показав: init.php на 3000 рядків, SQL-запити в шаблонах, одинаковий код скопійований в 12 компонентів, а додавання нового поля в каталозі вимагає правок у 8 місцях. Рефакторинг — це перетворення цього хаосу в поддерживаєму кодову базу без зміни зовнішньої поведінки сайту. Ключове слово — «без зміни поведінки»: рефакторинг не повинен ломити те, що працює.
Стратегія: не переписувати, а замішувати
Повна переписка Бітрікс-проекту — пастка. Бізнес-логіка, накопленої роками в шаблонах та обробниках, не описана у документації. Переписуючи з нуля, ви гарантовано втратите edge cases, які були впійманы хотфіксами.
Правильний підхід — інкрементальний рефакторинг: виділяєте один модуль, переписуєте його, перевіряєте, що поведінка ідентична, рухаєтеся далі. Кожна ітерація — робочий сайт.
Пріоритети рефакторингу
Порядок визначається по формулі: частота змін × складність зміни. Файли, які мінюються щотижня та в яких при цьому легко допустити помилку — рефакторити першими.
Пріоритет 1: Декомпозиція init.php.
Типовий «поганий» init.php містить:
- Обробники подій (
AddEventHandler) - Кастомні функції (хелпери форматування, генерація URL)
- Класи (іноді кілька в одному файлі)
- Пряму ініціалізацію (підключення до зовнішніх API при кожному хіті)
Цільовий стан: init.php містить тільки require_once автолоадера та реєстрацію обробників. Вся логіка — в окремих класах у /local/php_interface/classes/ або /local/modules/.
Структура /local/:
/local/
php_interface/
init.php → автолоадер + реєстрація
classes/
EventHandlers/ → обробники подій Бітрікса
Helpers/ → утиліти
Services/ → бізнес-логіка
modules/
project.core/ → кастомний модуль проекту
components/ → кастомні компоненти
templates/ → шаблони сайту
Міграція в /local/ — стандартна практика Бітрікса. Все в /local/ має пріоритет над /bitrix/, що дозволяє оновлювати ядро без конфліктів.
Пріоритет 2: Вилучення логіки з шаблонів компонентів.
Шаблон компонента (template.php) повинен містити тільки вивід HTML. Якщо в ньому є CIBlockElement::GetList(), $DB->Query(), складні обчислення — це проблема.
Три рівні рефакторингу:
-
result_modifier.php — перенос підготовки даних з
template.php. Найпростіший крок, не вимагає створення нового компонента. -
class.php — створення класу компонента, що успадковує
CBitrixComponent. МетодexecuteComponent()містить логіку,template.php— тільки вивід. -
Кастомний компонент у
/local/components/project/— коли стандартний компонент Бітрікса перестає відповідати вимогам.
Пріоритет 3: Заміна прямого SQL на D7 ORM.
Прямі запити через $DB->Query() — це:
- Відсутність екранування (SQL-інджекції)
- Прив'язка до конкретної СУБД
- Неможливість кешування через штатний механізм
Заміна на \Bitrix\Main\Entity\DataManager або мінімально на \Bitrix\Main\DB\Connection::query() з параметризованими запитами. Для інфоблоків — використання \Bitrix\Iblock\Elements\ElementXxxTable (D7 ORM для інфоблоків, доступно з ядра 21.x).
Пріоритет 4: Усунення дублювання.
Знаходите через phpcpd (PHP Copy/Paste Detector) одинакові блоки коду в різних шаблонах. Типовий паттерн: компонент catalog.section має 5 шаблонів з 80% одинакового коду, що відрізняються CSS-класами та порядком полів. Рішення: один шаблон з параметрами або include-файли для загальних блоків.
Процес безпечного рефакторингу
| Етап | Дія | Контроль |
|---|---|---|
| 1. Фіксація | Створення бекапу + git-коміт поточного стану | git init якщо проект не у VCS |
| 2. Тести | Написання smoke-тестів на критичні сторінки | HTTP-статусу, наявність ключових елементів |
| 3. Виділення | Перенос одного блока логіки в окремий клас | Тести проходять |
| 4. Підключення | Заміна старого коду викликом нового класу | Тести проходять |
| 5. Видалення | Видалення старого коду | Тести проходять |
| 6. Деплой | Виката на продакшн | Моніторинг помилок 24 години |
Кожен цикл — один логічний блок. Не рефакторьте кілька речей одночасно. При виникненні помилки на продакшені ви повинні точно знати, яка зміна її викликала.
Типові пастки
Рефакторинг без VCS. На дивовижу, значна частина Бітрікс-проектів досі не зберігається в Git. Перший крок рефакторингу — ініціалізація репозиторію з коректним .gitignore (виключити /bitrix/, /upload/, /vendor/, залишити /local/).
Перехід на D7 «за один раз». D7 API покриває не все. Старий API (CIBlockElement, CSale*) працює та підтримується. Переводите на D7 тільки той код, який рефакторите — не трогайте робочий старий код заради «консистентності».
Рефакторинг без моніторингу. Після виката рефакторингу стежте за b_event_log та серверними логами. Помилки можуть проявлятися не одразу, а при певних умовах: конкретний тип товару, певна група користувачів, специфічний браузер.
Оцінка строків
| Масштаб проекту | Типовий обсяг рефакторингу | Строк |
|---|---|---|
| Малий (до 50 кастомних файлів) | Декомпозиція init.php, очистка шаблонів | 3-5 днів |
| Середній (50-200 файлів) | + заміна SQL, усунення дублів | 1-2 тижні |
| Крупний (200+ файлів, кастомні модулі) | + міграція в /local/, створення модульної архітектури | 3-6 тижнів |
Рефакторинг — інвестиція. Його ефект вимірюється не візуально, а в швидкості подальшої розробки та кількості регресій при оновленнях.







