Хочешь войти в веб-разработку, работать с корпоративными сайтами и интернет-магазинами и при этом быть востребованным? 1С-Битрикс — крепкая платформа с большим рынком. Ниже — практическое руководство: что учить, как тренироваться, какие инструменты ставить и как собрать портфолио, чтобы уверенно брать реальные проекты.

Кто такой разработчик 1С-Битрикс и чем он занимается
Разработчик 1С-Битрикс — это бэкенд/фуллстек-инженер, который:
- проектирует структуру сайта (инфоблоки, highload-блоки, модули);
- пишет компоненты и шаблоны, дорабатывает готовые;
- интегрирует платёжные системы, 1С/ERP/CRM, сервисы доставки;
- оптимизирует производительность (кэш, композит, CDN), безопасность;
- автоматизирует рутину миграциями, CI/CD и тестами;
- поддерживает и развивает проект после релиза.
В работе ты будешь много писать PHP (ядро Bitrix), достаточно уверенно владеть JavaScript (включая BX.* API, Fetch/AJAX и иногда Vue/React), уверенно читать HTML/CSS, работать с SQL и Git.
Необходимые базовые знания (HTML, CSS, JS, PHP, SQL)
Минимум, с которым комфортно стартовать
- HTML5/CSS3: семантика, адаптив, сетки (Flex/Grid), БЭМ-подход.
- JavaScript: современный синтаксис (ES6+), Fetch/AJAX, модули, события. Для Bitrix пригодится знание BX.ajax, BX.ready, BX.bind и пр.
- PHP 8+: типы, ООП, исключения, пространства имён, Composer-автозагрузка, PSR-12.
- SQL: SELECT/INSERT/UPDATE/DELETE, индексы, JOIN, транзакции.
- Git: feature-ветки, Pull Request, rebase/merge, git-flow.
- Linux/Docker: базовые команды, работа с контейнерами, PHP-расширениями, Nginx/Apache, MariaDB/MySQL.
Совет: подтяни синтаксис и ООП в PHP, затем закрепи на мини-скриптах. Это даст уверенность при погружении в Bitrix-ядро (namespace Bitrix\…).
Изучение архитектуры и ядра 1С-Битрикс
Куда смотреть в проекте
- /local/ — твоя зона разработки: компоненты, шаблоны, модули. Не правь код в /bitrix/ (иначе обновления сотрут правки).
- local/components/ — собственные компоненты.
- local/templates/ — шаблоны сайта и стили.
- local/modules/ — кастомные модули.
- local/php_interface/ — точка входа для инициализации (события, автолоад).
Ключевые части платформы
- D7-ядро (современный слой): пространства имён, ORM, события, сервисы. Используй его вместо устаревших вызовов.
- ORM:
Bitrix\Main\ORMи таблицы модулей (например,Bitrix\Highloadblock\HighloadBlockTable). Для инфоблоков часто комбинируют ORM и удобные классыCIBlockElementиз-за полей/свойств. - События и обработчики:
Bitrix\Main\EventManager::getInstance()->addEventHandler(...). - Кэш: кэш компонентов,
Bitrix\Main\Data\Cache, tagged cache для инвалидации по тегам. - Настройки проекта:
.settings.php,.settings_extra.php,dbconn.php— разделяй dev/test/prod.
Что считать «современным» в коде
- ✅
\Bitrix\Main\Loader::includeModule('iblock'); - ✅ пространства имён и автозагрузка, строгие типы
declare(strict_types=1); - ✅ ORM/сервисы, исключения, явная работа с зависимостями
- ❌
CModule::IncludeModule()(старый стиль) - ❌ прямые
mysql_*вызовы - ❌ правки в
/bitrix/вместо/local/
Работа с компонентами, модулями и шаблонами
Структура своего компонента
/local/components/vendor/books.list/
.description.php
.parameters.php
class.php // логика компонента
templates/.default/
template.php
style.css
script.js
- .description.php — имя, категория.
- .parameters.php — параметры в визуальном редакторе.
- class.php — класс компонента (D7-подход).
- templates/... — верстка и JS.
Базовый каркас компонента (D7, кэш, AJAX-actions)
<?php
declare(strict_types=1);
use Bitrix\Main\Loader;
use Bitrix\Main\UI\PageNavigation;
use Bitrix\Main\Data\Cache;
use Bitrix\Main\Engine\Contract\Controllerable;
use Bitrix\Main\Engine\ActionFilter;
use Bitrix\Main\Engine\CurrentUser;
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) { die(); }
class BooksListComponent extends CBitrixComponent implements Controllerable
{
public function onPrepareComponentParams($params): array
{
$params['IBLOCK_ID'] = (int)($params['IBLOCK_ID'] ?? 0);
$params['PAGE_SIZE'] = max(1, (int)($params['PAGE_SIZE'] ?? 10));
$params['CACHE_TIME'] = (int)($params['CACHE_TIME'] ?? 3600);
return $params;
}
public function configureActions(): array
{
return [
'like' => [
'prefilters' => [
new ActionFilter\HttpMethod(['POST']),
new ActionFilter\Authentication(),
new ActionFilter\Csrf(),
],
],
];
}
protected function getFilter(): array
{
$request = \Bitrix\Main\Context::getCurrent()->getRequest();
$author = trim((string)$request->get('author'));
$filter = [
'IBLOCK_ID' => $this->arParams['IBLOCK_ID'],
'ACTIVE' => 'Y',
];
if ($author !== '') {
$filter['PROPERTY_AUTHOR'] = $author;
}
return $filter;
}
protected function loadItems(): void
{
if (!Loader::includeModule('iblock')) {
throw new \RuntimeException('Модуль iblock недоступен');
}
$cache = Cache::createInstance();
$nav = new PageNavigation('page');
$nav->setPageSize($this->arParams['PAGE_SIZE'])->initFromUri();
$cacheKey = md5(serialize([$this->getFilter(), $nav->getCurrentPage(), $nav->getPageSize()]));
$cacheDir = '/books/list';
if ($cache->initCache($this->arParams['CACHE_TIME'], $cacheKey, $cacheDir)) {
$this->arResult = $cache->getVars();
return;
}
if ($cache->startDataCache()) {
$select = [
'ID','IBLOCK_ID','NAME','DETAIL_PAGE_URL','PREVIEW_TEXT','DATE_ACTIVE_FROM',
'PROPERTY_AUTHOR',
];
$res = \CIBlockElement::GetList(
['SORT' => 'ASC', 'ID' => 'DESC'],
$this->getFilter(),
false,
[
'iNumPage' => $nav->getCurrentPage(),
'nPageSize' => $nav->getPageSize(),
'checkOutOfRange' => true,
],
$select
);
$items = [];
$nav->setRecordCount($res->NavRecordCount);
while ($el = $res->GetNextElement()) {
$f = $el->GetFields();
$p = $el->GetProperties();
$items[] = [
'ID' => (int)$f['ID'],
'NAME' => $f['~NAME'],
'URL' => $f['~DETAIL_PAGE_URL'],
'PREVIEW_TEXT' => $f['~PREVIEW_TEXT'],
'AUTHOR' => $p['AUTHOR']['~VALUE'] ?? null,
];
}
$this->arResult = [
'ITEMS' => $items,
'NAV' => $nav,
'FILTER'=> ['AUTHOR' => \Bitrix\Main\Text\HtmlFilter::encode($this->getFilter()['PROPERTY_AUTHOR'] ?? '')],
];
$cache->endDataCache($this->arResult);
}
}
public function executeComponent(): void
{
$this->loadItems();
$this->includeComponentTemplate();
}
public function likeAction(int $id): array
{
$userId = (int)CurrentUser::get()->getId();
if ($userId <= 0) {
throw new \Bitrix\Main\SystemException('Требуется авторизация');
}
\Bitrix\Main\Loader::includeModule('highloadblock');
$hl = \Bitrix\Highloadblock\HighloadBlockTable::getList([
'filter' => ['=NAME' => 'BookLikes'],
'limit' => 1,
])->fetch();
if (!$hl) {
throw new \Bitrix\Main\SystemException('HL-блок BookLikes не найден');
}
$entity = \Bitrix\Highloadblock\HighloadBlockTable::compileEntity($hl);
$dataClass = $entity->getDataClass();
$exists = $dataClass::getList([
'filter' => ['UF_USER_ID' => $userId, 'UF_ITEM_ID' => $id],
'limit' => 1,
])->fetch();
if ($exists) {
$dataClass::delete((int)$exists['ID']);
$liked = false;
} else {
$dataClass::add(['UF_USER_ID' => $userId, 'UF_ITEM_ID' => $id]);
$liked = true;
}
$count = $dataClass::getCount(['UF_ITEM_ID' => $id]);
return ['liked' => $liked, 'count' => $count];
}
}
Шаблон компонента (фрагмент)
templates/.default/template.php
<?php if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die(); ?>
<form method="get" class="books-filter">
<label>
Автор:
<input type="text" name="author" value="<?= $arResult['FILTER']['AUTHOR'] ?>">
</label>
<button type="submit">Фильтровать</button>
</form>
<ul class="books">
<?php foreach ($arResult['ITEMS'] as $item): ?>
<li class="book">
<a href="<?= $item['URL'] ?>"><?= htmlspecialcharsbx($item['NAME']) ?></a>
<?php if ($item['AUTHOR']): ?>
<div class="book__meta">Автор: <?= htmlspecialcharsbx($item['AUTHOR']) ?></div>
<?php endif; ?>
<div class="book__text"><?= $item['PREVIEW_TEXT'] ?></div>
<button class="book__like" data-like-id="<?= (int)$item['ID'] ?>">
❤ <span data-like-count>0</span>
</button>
</li>
<?php endforeach; ?>
</ul>
<?php
$APPLICATION->IncludeComponent(
'bitrix:main.pagenavigation',
'',
[
'NAV_OBJECT' => $arResult['NAV'],
'SEF_MODE' => 'N',
],
false
);
templates/.default/script.js
BX.ready(function () {
document.addEventListener('click', function (e) {
const btn = e.target.closest('[data-like-id]');
if (!btn) return;
const id = parseInt(btn.dataset.likeId, 10);
BX.ajax.runComponentAction('vendor:books.list', 'like', {
mode: 'class',
data: { id: id }
}).then(function (response) {
const data = response.data;
btn.classList.toggle('is-liked', !!data.liked);
const cnt = btn.querySelector('[data-like-count]');
if (cnt) cnt.textContent = data.count;
}).catch(function (err) {
const message = (err && err.errors && err.errors[0] && err.errors[0].message) || 'Ошибка';
alert(message);
});
});
});
Практика: создание простого проекта «с нуля»
Цель: одностраничный каталог книг с фильтром по автору и лайками.
- Подними окружение
Docker-композ: Nginx + PHP-FPM + MariaDB. В PHP добавь расширения:mbstring,intl,zip,gd/imagick,opcache,mysqli. Включиxdebugдля отладки (dev-сборка). - Установи чистый Битрикс
Разворачивай с пустым шаблоном. Сразу создай/local/и настрой в IDE (PhpStorm) инспекции, PHPStan/Psalm и PHP-CS-Fixer. - Создай инфоблок «Книги»
Поля: Название, Анонс. Свойства:AUTHOR(строка). Добавь пару тестовых элементов. - Сделай HL-блок
BookLikes
Поля:UF_ITEM_ID(int, индекс),UF_USER_ID(int, индекс). Это наш счётчик лайков. - Собери компонент
vendor:books.list
Положи код из раздела выше в/local/components/vendor/books.list/.
Параметры:IBLOCK_ID,PAGE_SIZE=10,CACHE_TIME=3600. - Подключи на страницу
На странице/books/index.php:
<?php
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/header.php');
$APPLICATION->SetTitle('Каталог книг');
$APPLICATION->IncludeComponent('vendor:books.list','',[
'IBLOCK_ID' => 3, // подставь ID инфоблока
'PAGE_SIZE' => 10,
'CACHE_TIME' => 3600
]);
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/footer.php');
7. Проверь кэш и навигацию
Меняй фильтр — кэш-ключ должен учитывать автора и страницу. Для точной инвалидации при изменении инфоблока подключай tagged cache.
Изучение архитектуры глубже: ORM, события, кэш
ORM-пример: Highload-блок как сущность
use Bitrix\Highloadblock\HighloadBlockTable;
use Bitrix\Main\Loader;
Loader::includeModule('highloadblock');
$hl = HighloadBlockTable::getByPrimary(5)->fetchObject(); // ID HL-блока
$entity = HighloadBlockTable::compileEntity($hl);
$Likes = $entity->getDataClass();
$list = $Likes::getList([
'filter' => ['UF_ITEM_ID' => 123],
'select' => ['ID','UF_USER_ID','UF_ITEM_ID']
])->fetchCollection();
События (пример — после добавления элемента инфоблока)
use Bitrix\Main\EventManager;
EventManager::getInstance()->addEventHandler(
'iblock',
'OnAfterIBlockElementAdd',
static function(array $fields) {
if ((int)$fields['IBLOCK_ID'] === 3) {
// Очистить тег кэша при изменениях каталога книг
$tc = new \Bitrix\Main\Data\TaggedCache();
$tc->clearByTag('iblock_id_3');
}
}
);
Tagged cache в компоненте
$tagged = new \Bitrix\Main\Data\TaggedCache();
$tagged->startTagCache($cacheDir);
$tagged->registerTag('iblock_id_'.$this->arParams['IBLOCK_ID']);
$tagged->endTagCache();
Где брать реальные задачи и как собирать портфолио
Источники задач:
- Свой мини-проект (как наш каталог) — выложи код в публичный репозиторий (например, Git).
- Волонтёрство для НКО/локального бизнеса: лендинги, каталоги, блоги на Bitrix.
- Микро-задачи: правки компонентов, миграции, интеграция оплаты/доставки, оптимизация скорости.
- Участие в командных пет-проектах: роль backend, devops или интегратор.
Что положить в портфолио:
- 2–3 проекта разных типов (контент-сайт, каталог/магазин, интеграция).
- Код компонента с AJAX-action, пример модуля, пример миграции (создание инфоблока/HL-блока кодом).
- Скриншоты админки и витрины, краткое описание задач и измеримые результаты (время загрузки, конверсия, TTFB до/после).
Как презентовать:
- Короткие README: стек, зачем, как запустить (Docker-композ), что реализовано.
- Нормальные коммиты, линтеры, CI (PHPStan/Psalm, тесты).
- Пара абзацев про архитектурные решения и компромиссы.
Сертификация и карьерный рост
Линейка ролей:
- Junior Bitrix Developer: компоненты, шаблоны, инфоблоки, базовый кэш, простые интеграции.
- Middle: сложные компоненты, highload-структуры, миграции, интеграции с 1С/CRM, безопасность, композит, SPA/SSR-витрины.
- Senior/Team Lead: архитектура, модули, highload-нагрузка, шардирование, DevOps, аудит, менторство.
Сертификация:
- «Разработчик Bitrix Framework» — концентрируется на ядре, компонентах, ORM и кэше.
- «Администратор» — про инфраструктуру, композит, производительность.
- «Интеграция с 1С» — обмен, каталоги, цены/остатки.
Готовься по задачам из реальных проектов: компоненты с кэшем, события, ORM, интеграции и безопасность.
Полезные советы и типичные ошибки новичков
Советы
- Всегда работай в
/local/. Шаблоны, компоненты, модули — только там. - D7 и неймспейсы. Пиши новый код на D7, соблюдай PSR-12, используй строгие типы.
- Кэш-политика. На чтении — кэшируй, на изменении — инвалидируй теги. Не кэшируй персональные данные без ключей пользователя.
- Безопасность. XSS — через
htmlspecialcharsbx, CSRF — через фильтрActionFilter\Csrf, проверяй права (\Bitrix\Main\Engine\CurrentUser). - Производительность. Меньше запросов к БД, индексы по фильтрам, не трогай
SELECT *. Включи опкеш, профилируй «Монитором производительности». - Миграции. Держи структуру (инфоблоки, HL-блоки, типы почтовых событий) в коде. Без ручных кликов на проде.
- Git и ревью. Короткие PR/коммиты, код-ревью, читайте диффы.
- CI/CD. Автосборка, деплой без «запрыгивания на прод».
- Логи и мониторинг.
\Bitrix\Main\Diag\Debug::writeToFileна dev, централизованный сбор логов на prod. - Учись читать ядро. Много ответов — в исходниках модулей.
Ошибки
- Патчить файлы в
/bitrix/→ потеряешь на обновлении. - Смешивать верстку и бизнес-логику в шаблоне → расширяй компонент.
- Делать 20 запросов в цикле по элементам → собери ID, сделай один батч.
- Отсутствие кэша или невалидируемый кэш → перегенерируй по тегам.
- Хардкодить пути/ID → выноси в параметры/константы/настройки.
- Игнорировать обработку ошибок/исключений → заваливаешь страницу вместо graceful-fail.
Дополнительно: примеры, которые пригодятся каждый день
Мини-миграция создания HL-блока (внутри модуля/скрипта установки)
use Bitrix\Highloadblock\HighloadBlockTable;
$addRes = HighloadBlockTable::add([
'NAME' => 'BookLikes',
'TABLE_NAME' => 'b_hl_book_likes',
]);
$hlId = (int)$addRes->getId();
// Добавь пользовательские поля UF_ITEM_ID, UF_USER_ID через CUserTypeEntity::Add
Проверка прав доступа (например, только для редакторов)
use Bitrix\Main\Engine\CurrentUser;
$current = CurrentUser::get();
if (!$current->isAdmin() && !$current->canDoOperation('edit_other_settings')) {
throw new \Bitrix\Main\AccessDeniedException('Недостаточно прав');
}
Ручной AJAX с Fetch + CSRF
fetch('/local/ajax/like.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: 123, sessid: BX.bitrix_sessid() })
}).then(r => r.json()).then(console.log);
Транзакция в D7
$connection = \Bitrix\Main\Application::getConnection();
$connection->startTransaction();
try {
// ... твои DML-операции
$connection->commitTransaction();
} catch (\Throwable $e) {
$connection->rollbackTransaction();
throw $e;
}
Дорожная карта на 90 дней
- Недели 1–2: HTML/CSS/JS база, современный PHP 8, Git. Подними локальное окружение (Docker).
- Недели 3–4: Введение в Bitrix: структура проекта, инфоблоки/HL-блоки, настройка шаблона.
- Недели 5–6: Свой компонент: фильтр, пагинация, кэш. JS-интерактив (AJAX-action).
- Недели 7–8: ORM, события, tagged cache, оптимизация запросов, безопасность.
- Недели 9–10: Миграции, простая интеграция (например, веб-хуки/платёжка).
- Недели 11–12: Проект для портфолио, ревью кода, подготовка к сертификации.
Итог
Стать разработчиком на 1С-Битрикс — это не про «магические галочки в админке», а про инженерный подход: чистый код, D7-ядро, кэш и безопасность, миграции и автоматизация. Начни с малого — собери свой компонент, добавь фильтр и лайки, заверни всё в кэш, подружись с ORM и событиями. Через пару месяцев уверенной практики ты сможешь брать реальные задачи и расти до мидла, а дальше — специализироваться на e-commerce, интеграциях или высоконагруженных проектах.