Сторонняя библиотека в проекте - composer, автозагрузка, выкладка
Подключаем стороннюю библиотеку так, чтобы она пережила обновление платформы, доехала до боевого сайта и не поссорилась с автозагрузкой ядра.
Что нужно знать заранее
В проекте работают два автозагрузчика сразу: свой у платформы и свой у менеджера зависимостей. Они не знают друг о друге и просто стоят в общей очереди, поэтому важен порядок их подключения.
Каталог ядра при обновлении перезаписывается целиком. Всё своё - описание зависимостей, установленные библиотеки и код проекта - держат в отдельном каталоге, который обновление не трогает.
Автозагрузчик библиотек нужен во всех режимах работы, а не только на витрине. Административный раздел, фоновые задания и консольные скрипты используют те же классы и падают первыми при неверном подключении.
Шаги
- Положить описание зависимостей в свой каталог, а не в каталог платформы.
- Установить библиотеку менеджером зависимостей и проверить появление каталога библиотек.
- Подключить автозагрузчик один раз, в файле инициализации своего каталога.
- Решить, что попадает в репозиторий: описание с замком версий или сами библиотеки.
- Добавить установку зависимостей в порядок выкладки на боевой сайт.
Решение
Кладём описание зависимостей в свой каталог:
cd /home/site/www/localcomposer require guzzlehttp/guzzle:^7.0 # библиотека приедет в local/vendorls -d /home/site/www/local/vendor # каталог ядра при этом не трогаемcat /home/site/www/local/composer.json # описание зависимостей проекта# то же самое подходит и для каталога /local на многосайтовой копииКаталог платформы обновление перезаписывает целиком, вместе со всем, что туда положили. Описание зависимостей и установленные библиотеки живут в своём каталоге и переживают любое обновление продукта.
Подключаем автозагрузчик один раз:
// /local/php_interface/init.php - выполняется на каждом запросеrequire_once $_SERVER['DOCUMENT_ROOT'] . '/local/vendor/autoload.php';// подключение в шаблоне сайта не работает в админке, агентах и консолиФайл инициализации выполняется в любом режиме работы платформы. Подключение из шаблона сайта выглядит рабочим до первого фонового задания, а потом даёт ошибку об отсутствующем классе.
Регистрируем своё пространство имён:
\Bitrix\Main\Loader::registerNamespace('Vendor\\Project', '/local/lib');// свой код можно отдать и автозагрузчику платформы, а не только менеджеру$service = new \Vendor\Project\Service\OrderExport();Свой код подключают любым из двух способов, но не обоими сразу. Смешение путает разработчиков и приводит к странным ошибкам после переноса проекта на другой сервер.
Проверяем, что библиотека действительно загружается:
var_dump(class_exists(\GuzzleHttp\Client::class)); // true - автозагрузчик работаетvar_dump(\Composer\InstalledVersions::getVersion('guzzlehttp/guzzle'));// проверку удобно держать отдельным служебным скриптом в своём каталогеПроверка занимает секунду и снимает вопрос «поставилось или нет» на любом стенде. Печать установленной версии дополнительно показывает, совпадает ли она с той, что записана в замке версий проекта.
Версионируем описание, а не библиотеки:
git add local/composer.json local/composer.lockecho 'local/vendor/' >> .gitignore # библиотеки ставит команда выкладкиgit commit -m "библиотека для работы с HTTP"git log --oneline -1 -- local/composer.lock # замок версий обязан быть в историиЗамок версий фиксирует точные версии библиотек и обязан лежать в репозитории. Без него разработчик и боевой сайт получают разные версии, и ошибка воспроизводится только у одного из них.
Ставим зависимости при выкладке:
composer install --no-dev --optimize-autoloader --working-dir=/home/site/www/local# без этой команды на боевом сайте не окажется ни одной библиотекиУстановку зависимостей добавляют в порядок выкладки рядом со сборкой фронтенда. Флаг без разработческих пакетов убирает тесты и отладочные инструменты, которые на боевом сайте не нужны.
Типичные проблемы
После обновления платформы библиотеки исчезли.
Описание зависимостей и каталог библиотек лежали внутри каталога ядра. Обновление перезаписывает его целиком, поэтому своё держат в отдельном каталоге.
Класс не найден в админке или в фоновом задании.
Автозагрузчик подключён в шаблоне сайта, который в этих режимах не выполняется. Подключение переносят в файл инициализации своего каталога.
На боевом сайте нет ни одной библиотеки.
Каталог библиотек не версионируется, а установка зависимостей в порядок выкладки не добавлена. Команду установки ставят рядом со сборкой фронтенда.
Ошибка появляется только на сервере, а на стенде всё работает.
Различается регистр имён файлов, а файловая система сервера к нему чувствительна. Имена файлов приводят к одному виду и проверяют на копии боевого окружения.
Библиотека конфликтует с версией из платформы.
Та же библиотека уже поставляется вместе с продуктом и загружается первой. Версии сверяют до установки и при конфликте берут ту, что уже есть.
Частые вопросы
Класть ли каталог библиотек в репозиторий?
Обычно нет: в репозитории держат описание и замок версий. Исключение - выкладка без доступа к сети, когда библиотеки приходится нести с собой.
Где именно подключать автозагрузчик?
В файле инициализации своего каталога, до первого обращения к классам библиотеки. Так он работает и на витрине, и в админке, и в консольных скриптах.
Можно ли обойтись без менеджера зависимостей?
Можно, но обновлять и сверять версии придётся руками. Для одной маленькой библиотеки это допустимо, для нескольких - уже нет.
Что делать при конфликте версий?
Смотреть, кто требует конфликтующую версию, и по возможности брать ту, что уже есть в проекте. Две версии одной библиотеки в одном процессе не уживаются.
Ускоряет ли что-нибудь автозагрузку?
Да, сборка оптимизированной карты классов при установке зависимостей. На боевом сайте её включают всегда, на стенде она мешает частым правкам.
Смежное
- Class not found: причины по убыванию частоты - разбор ошибки после невыложенных библиотек
- Git и выкладка - оглавление подтемы
- Свой модуль или код в проекте: когда пора выносить в модуль - где живёт код, который их использует
- Git в проекте: что версионировать, что игнорировать - что попадает в репозиторий
- Выкладка на боевой: порядок, структура, откат - куда добавить установку зависимостей
- Проверки перед выкладкой: синтаксис, стандарт, тесты, миграции - проверки рядом с установкой
- Свой модуль: структура, установка, автозагрузка - автозагрузка своего кода
- Выгрузка в Excel из кода: библиотека, объём, отдача файла - типовая сторонняя библиотека
- Composer и PSR-4 в 1С-Битрикс - устройство автозагрузки целиком