Composer в Битрикс подключаю в любом проекте, где нужно что-то серьёзнее, чем скопировать чужой php-файл в /local и надеяться, что он не развалится при следующем обновлении модуля. За несколько лет работы с интернет-магазинами на 1С-Битрикс я перепробовал разные способы затащить внешние SDK: ручное копирование исходников, git submodule, скачивание архива с GitHub и вставку файлов руками. Composer оказался единственным вариантом, который не превращается в головную боль при обновлении зависимостей и переносе проекта на новый сервер. Дальше показываю, куда его ставить в структуре Битрикса, как настроить автозагрузку рядом с ядром и на что натыкался при подключении реальных библиотек вроде Guzzle и SDK СДЭК.
Зачем подключать Composer в проекте на Битрикс
Типовая задача на живом проекте: принять платёж через Т‑Банк, посчитать доставку через СДЭК, выгрузить остатки в Excel для бухгалтерии, залогировать ошибки интеграции отдельно от логов ядра. Каждую из этих задач можно закрыть без Composer, руками подключив нужный класс через require. Но как только библиотек становится больше двух-трёх и у них появляются собственные зависимости, ручное управление превращается в раскладывание карточного домика: обновил одну библиотеку - сломал совместимость с другой, потерял файл при переносе на сервер - получил белый экран в проде.
Composer решает это одним файлом composer.json, где написано, что именно нужно проекту и в каких версиях. Файл composer.lock фиксирует точные версии всех зависимостей, включая вложенные, поэтому у меня на компьютере и на сервере клиента ставится один и тот же набор пакетов, а не «более свежая версия, которая внезапно всё сломала».
Отдельный момент - решения из Маркетплейса Битрикса. Некоторые модули таскают сторонние библиотеки прямо у себя в папке, отдельно от composer-зависимостей проекта. Это рабочий, но замкнутый на себя способ: такая копия не участвует в общем дереве зависимостей и не обновляется вместе с твоим кодом, из-за чего потом возникают дубли классов - об этом отдельно ниже.
Куда встраивать Composer в структуре 1С-Битрикс
По умолчанию система ищет composer.json в папке /home/bitrix/www/bitrix/, но документация рекомендует размещать его за пределами DOCUMENT_ROOT, например в /home/bitrix/, чтобы конфигурация не была доступна публично, и указывать путь к файлу в /bitrix/.settings.php. Если вынести файл за пределы DOCUMENT_ROOT нельзя, для него создают папку /local/composer/ и закрывают её от доступа извне. Ключевое правило: папку /bitrix через Composer не трогаю вообще. Это проприетарное ядро, которое живёт своей жизнью и обновляется через собственный механизм обновлений Битрикса, а не через composer update. Пытаться подключить туда пакеты или переписать структуру - верный способ получить конфликт при следующем плановом обновлении платформы.
Всё, что нужно моему коду, кладу в /local/php_interface/lib - эту структуру я создаю сам, Битрикс её не трогает. Вот минимальный composer.json для такого проекта:
{
"name": "kalinkindev/bitrix-project",
"type": "project",
"require": {
"php": ">=7.4",
"guzzlehttp/guzzle": "^7.0"
},
"config": {
"platform": {
"php": "7.4.33"
},
"optimize-autoloader": true
},
"autoload": {
"psr-4": {
"Local\\": "local/php_interface/lib/"
}
}
}
Секция config.platform.php - не декоративная. У меня был случай, когда локально стоял PHP 8.2, а хостинг клиента держал 7.4. Composer без пина платформы честно поставил версии пакетов под 8.2, на сервере всё легло с ошибкой несовместимости. После того как прописал platform.php с версией сервера, composer install начал считать зависимости от реального окружения, а не от того, что стоит у меня на машине.
Бесплатный материал
🎁 Полезный скрипт в подарок
Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.
Без спама. Отписка в 1 клик.
Автозагрузка классов: PSR‑4 рядом с ядром Битрикс
После composer install зависимости лежат в папке /vendor, которую Composer создаёт рядом с composer.json, а автозагрузчик /vendor/autoload.php подключается автоматически. Отдельно требовать его в init.php не нужно, достаточно один раз показать системе, где лежит composer.json, через /bitrix/.settings.php:
<?php
return [
'composer' => [
'value' => [
'config_path' => '/home/bitrix/composer.json'
]
]
];
С этого момента доступны и внешние пакеты, и мои собственные классы из namespace Local, который я прописал в psr‑4 выше. Например, класс для расчёта зоны доставки кладу в local/php_interface/lib/Delivery/ZoneCalculator.php:
<?php
namespace Local\Delivery;
class ZoneCalculator
{
public function calculate(string $cityCode): array
{
return ['zone' => $cityCode, 'days' => 3];
}
}
Использовать его можно в любом обработчике или компоненте Битрикса:
<?php
use Local\Delivery\ZoneCalculator;
$calculator = new ZoneCalculator();
$result = $calculator->calculate('MSK');
Конфликтов с собственным автозагрузчиком Битрикса на практике почти не бывает: старые классы ядра живут в глобальном пространстве имён (CIBlockElement, CSaleOrder и подобные), новый D7-слой - в пространстве Bitrix\, а composer-пакеты используют собственные вендорские namespace вроде GuzzleHttp\ или PhpOffice\. Пересечься они могут только если сторонняя библиотека по недосмотру объявляет класс без namespace - для современных пакетов с packagist.org это редкость.
После любого изменения состава зависимостей на проде запускаю оптимизацию автозагрузки, чтобы Composer собрал classmap заранее и не искал файлы через дерево psr‑4 на каждый запрос:
composer dump-autoload --optimize --no-dev
Подключаю сторонние библиотеки на практике: Guzzle, СДЭК, Т‑Банк
Вот что реально ставлю через Composer на проектах с Битриксом:
| Библиотека | Что закрывает |
|---|---|
| guzzlehttp/guzzle | HTTP-запросы к внешним API: СДЭК, Т‑Банк, курсы валют ЦБ |
| phpoffice/phpspreadsheet | Экспорт заказов и остатков в Excel без ручной сборки XML |
| monolog/monolog | Логи интеграций отдельно от штатных логов Битрикса, чтобы не рыться в общей каше при отладке |
Для СДЭК логика такая: сначала получаю OAuth-токен, потом уже дёргаю методы расчёта доставки или создания заказа. С Guzzle это выглядит так:
<?php
use GuzzleHttp\Client;
$client = new Client(['base_uri' => 'https://api.cdek.ru']);
$response = $client->post('/v2/oauth/token', [
'form_params' => [
'grant_type' => 'client_credentials',
'client_id' => CDEK_CLIENT_ID,
'client_secret' => CDEK_CLIENT_SECRET,
],
]);
$token = json_decode((string) $response->getBody(), true)['access_token'];
Дальше этим токеном подписываю все последующие запросы к методам расчёта тарифов и зон доставки. У Т‑Банка (бывший Тинькофф) логика приёма платежей устроена похоже: инициация платежа - это POST-запрос с телом в JSON, где обязательно передаётся идентификатор терминала, сумма заказа и подпись запроса, рассчитанная по алгоритму из документации эквайринга. Официальный SDK Т‑Банка можно подключить как composer-репозиторий типа vcs, если пакета нет на Packagist, тогда в composer.json добавляется секция repositories с адресом git-репозитория SDK.
Если интеграция сложная и завязана сразу на несколько сервисов (эквайринг, доставка, складской учёт), обычно проще заказать её под ключ, чем собирать по кускам из документации трёх разных провайдеров, и в такую работу я закладываю сразу настройку всех нужных SDK через Composer.
Конфликты Composer с модулями Битрикса и как их избегать
Самая частая проблема на практике - не сам Composer, а модули из Маркетплейса, которые тащат внутри себя копию той же библиотеки, что я подключаю через composer require. Например, модуль для интеграции со сторонней CRM держит у себя в папке собственный Guzzle без пространства имён вендора или со старой версией. Итог - Fatal error: Cannot redeclare class при попытке одновременно использовать модульную копию и composer-версию.
Что делаю в таких случаях:
- Смотрю, действительно ли класс дублируется по имени и namespace, а не просто совпадает по названию файла.
- Если модуль подключает библиотеку через собственный require, а не через глобальный vendor/autoload.php, оборачиваю точку подключения проверкой class_exists(), чтобы не было повторной загрузки.
- Фиксирую версию php в config.platform, чтобы Composer не подтягивал пакеты, требующие более новую версию, чем есть на хостинге.
- Держу composer.lock в репозитории - без него на сервере при переустановке могут прилететь другие минорные версии зависимостей, и совместимость с модулем внезапно пропадёт.
Если проект уже оброс десятком интеграций и модулей, отслеживать такие конфликты вручную после каждого обновления Битрикса или модуля становится отдельной работой - под это у меня есть техническая поддержка сайта от 15 000 ₽/мес, куда как раз входит проверка совместимости после обновлений.
Деплой: переношу vendor на сервер в 3 шага
Многие тарифы хостинга для Битрикса не дают SSH-доступа или блокируют функции вроде proc_open, без которых composer install не запустить прямо на сервере. Поэтому процесс переноса зависимостей на прод у меня всегда одинаковый и укладывается в 3 шага:
Шаг 1. Собираю зависимости локально
На своей машине или в CI выполняю composer install - no-dev - optimize-autoloader с тем же platform.php, что указан в config хостинга, чтобы не поймать несовместимость версий уже на сервере.
Шаг 2. Коммичу vendor или собираю артефакт в CI
Если SSH на хостинге нет, папку vendor приходится коммитить в репозиторий целиком - не самое элегантное решение, зато рабочее без доступа к консоли сервера. Если SSH есть, честнее собирать vendor в пайплайне (например, в GitHub Actions) и разворачивать уже готовый артефакт, не держа vendor в git постоянно.
Шаг 3. Заливаю на сервер через git pull или rsync
Дальше обычный деплой: git pull на сервере или rsync с локальной сборки, включая vendor и composer.lock. Отдельно закрываю папку vendor от прямых обращений через настройки веб-сервера, чтобы никто не мог открыть исходники зависимостей по прямой ссылке - вынести её выше корня сайта на большинстве тарифов Битрикс-хостинга нельзя, поэтому закрываю доступ на уровне веб-сервера.
1С-Битрикс регулярно обновляется, поэтому перед внедрением я сверяюсь с актуальной документацией.
Частые вопросы
Можно ли поставить Composer прямо в папку /bitrix?
Не стоит. Папка /bitrix - это проприетарное ядро платформы, оно обновляется через собственный механизм обновлений Битрикса, и любое вмешательство в её структуру через Composer или вручную создаёт риск конфликта при следующем плановом обновлении. Все зависимости и собственный код держу в /local, ядро не трогаю.
Что делать, если на хостинге нет SSH и composer install не запустить?
Собираю зависимости локально или в CI-пайплайне с тем же составом php-расширений и версией PHP, что на сервере, а затем переношу готовую папку vendor вместе с composer.lock через git или загрузку по FTP. На сервере после этого ничего собирать не нужно, всё уже готово.
Почему Composer ставит не те версии пакетов, что нужны на сервере?
Обычно причина в том, что Composer ориентируется на PHP-версию и расширения той машины, где запускается install. Если локально стоит более новая версия PHP, чем на хостинге, пакеты подбираются под неё и потом не работают на проде. Решение - прописать точную версию сервера в config.platform.php в composer.json.
Нужно ли закрывать доступ к папке vendor снаружи?
Да, если она оказалась внутри DOCUMENT_ROOT. Composer создаёт vendor рядом с composer.json, поэтому при composer.json в корне сайта папка доступна по прямому URL. Документация советует держать composer.json за пределами DOCUMENT_ROOT, а если это невозможно, положить его в /local/composer/ и закрыть эту папку от доступа извне. Добавляю правило в настройках веб-сервера, запрещающее отдачу файлов из vendor напрямую, поскольку вынести её выше корня сайта на типичном Битрикс-хостинге обычно нельзя.