Главная / База знаний / Composer: управление зависимостями PHP-проекта
инструкция · 3 октября 2026

Composer: управление зависимостями PHP-проекта

Разбираем, что решает Composer, зачем нужен composer.lock, чем отличаются composer install и composer update, и как ставить зависимости на VPS с ограниченной памятью.

Зачем нужен Composer

До появления Composer PHP-разработчики подключали сторонние библиотеки вручную: скачивали архив с исходным кодом, распаковывали его в проект, прописывали require_once на нужные файлы и вручную следили, чтобы одна библиотека не тянула за собой конфликтующую версию другой. Такой подход быстро превращался в хаос на любом проекте крупнее одностраничного сайта — особенно когда несколько библиотек полагались на разные версии одной и той же третьей зависимости.

Composer решает эту проблему как менеджер зависимостей: он читает список нужных пакетов и их допустимых версий из файла composer.json, вычисляет граф совместимых версий с учётом требований каждой зависимости друг к другу, скачивает нужные файлы из репозитория Packagist (или другого источника) и генерирует единый автозагрузчик классов, через который всё это подключается в коде одной строкой.

Второй, менее очевидный, но не менее важный результат работы Composer — воспроизводимость. Если весь процесс установки на разных машинах даёт ровно один и тот же набор версий библиотек, разработчик на своём ноутбуке, сервер тестового окружения и production-сервер работают с идентичным кодом сторонних зависимостей, а не с случайно разными версиями, полученными в разное время.

Эта статья разбирает, как устроены composer.json и composer.lock, чем отличаются установка и обновление зависимостей, как работает автозагрузка классов по стандарту PSR-4, и что делать, если процесс установки упирается в ограничения небольшого VPS по памяти.

Установка Composer на VPS

Composer — это не пакет из репозитория дистрибутива в привычном смысле, а отдельный исполняемый PHP-скрипт (phar-архив), который принято ставить глобально в систему через официальный установочный скрипт, а не через устаревшую версию из apt.

Официальный способ установки Composer в системный PATH
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php --install-dir=/usr/local/bin --filename=composer
php -r "unlink('composer-setup.php');"

Флаг --install-dir указывает, куда поместить исполняемый файл (обычно /usr/local/bin, который уже есть в PATH на большинстве дистрибутивов), а --filename задаёт имя команды — после этого шага composer можно вызывать из любой директории без указания полного пути.

Проверка установленной версии и базовая диагностика окружения Composer
composer --version
composer diagnose

Команда composer diagnose полезна сразу после установки: она проверяет доступность сети, права на директории кэша, версию PHP и включённые расширения, и заранее подсвечивает проблемы окружения, которые иначе всплыли бы только в момент первой реальной установки зависимостей проекта.

composer.json: структура файла зависимостей

composer.json — центральный конфигурационный файл проекта, описывающий его имя, зависимости и правила автозагрузки классов. Он создаётся один раз (вручную или командой composer init) и затем редактируется по мере добавления новых библиотек.

Минимальный composer.json с production- и dev-зависимостями и правилом автозагрузки
{
    "name": "acme/site",
    "require": {
        "php": ">=8.2",
        "monolog/monolog": "^3.0",
        "guzzlehttp/guzzle": "^7.8"
    },
    "require-dev": {
        "phpunit/phpunit": "^10.0"
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

Секция require, помимо сторонних пакетов, часто содержит и требование к самому PHP (php: >=8.2) — это не устанавливает интерпретатор автоматически, а лишь фиксирует минимальную версию, при попытке установки на сервере со старым PHP Composer сразу сообщит о несовместимости вместо непредсказуемого падения приложения уже во время работы.

Операторы версий в require — отдельная важная деталь: символ ^ перед версией (^3.0) разрешает обновления в пределах совместимой мажорной версии по правилам семантического версионирования, тильда (~7.8) ограничивает диапазон ещё туже, а точная версия без операторов жёстко фиксирует её без каких-либо автоматических обновлений вообще.

require и require-dev: разделение по назначению

Не все зависимости нужны на production-сервере в равной степени. Библиотеки для тестирования (PHPUnit), статического анализа кода (PHPStan, Psalm) или отладки нужны только разработчику на этапе написания и проверки кода — на боевом сервере они лишь занимают место и потенциально расширяют поверхность возможных уязвимостей без какой-либо пользы.

Добавление production-зависимости и dev-зависимости отдельными командами
composer require monolog/monolog
composer require --dev phpunit/phpunit

Флаг --dev записывает пакет в секцию require-dev вместо require. При установке на production-сервере используется флаг --no-dev, который полностью пропускает все dev-зависимости, ускоряя установку и уменьшая итоговый размер папки vendor.

Типичная команда установки зависимостей на production-сервере
composer install --no-dev --optimize-autoloader

Флаг --optimize-autoloader дополнительно ускоряет автозагрузку классов в production, заранее строя оптимизированную карту классов вместо динамического поиска файлов по правилам PSR-4 на каждый запрос — на проектах с большим числом классов разница в скорости первого обращения к каждому классу заметна, особенно при высокой нагрузке.

composer.lock: почему обязательно коммитить в репозиторий

Версии в composer.json — это диапазоны допустимых значений, а не точная фиксация конкретной версии: запись ^3.0 разрешает установку и 3.0.0, и 3.4.2, и любой другой версии в пределах третьей мажорной ветки, которая существует на момент установки. Сам по себе composer.json ничего не говорит о том, какая именно версия была фактически установлена и протестирована.

composer.lock решает эту проблему: после разрешения графа зависимостей Composer записывает в него точные версии всех установленных пакетов вместе с контрольными суммами их содержимого. Пока composer.lock присутствует в проекте, команда composer install берёт версии именно из него, полностью игнорируя диапазоны из composer.json — то есть install гарантированно ставит один и тот же набор версий на любой машине, где выполняется, будь то ноутбук разработчика, CI-раннер или production-сервер.

Файл composer.lock существует именно для того, чтобы зафиксировать, какая версия каждой зависимости была реально протестирована — не коммитить его означает добровольно отказаться от воспроизводимости сборки.

Принцип из официальной документации Composer

Практическое следствие для безопасности: без committed composer.lock повторная установка зависимостей на production через несколько месяцев после первого деплоя может незаметно подтянуть новую минорную или патч-версию какой-то транзитивной зависимости, вышедшую за это время, — включая версию с новой уязвимостью, несовместимым поведением или попросту неожиданным багом, которого не было на момент тестирования релиза.

Единственный файл, который в этой связке действительно не нужно коммитить, — сама папка vendor. Она полностью восстанавливается из composer.lock командой composer install на любой машине и обычно занимает заметный объём, а иногда содержит платформо-зависимые бинарные файлы, собранные под конкретную архитектуру или ОС, что делает её хранение в Git не только избыточным, но и потенциально проблемным при переносе между разными окружениями.

composer install и composer update: в чём реальная разница

Эти две команды — источник самой частой путаницы у новичков, хотя разница между ними принципиальна и напрямую связана с composer.lock из предыдущего раздела. composer install читает существующий composer.lock и устанавливает ровно те версии, что в нём зафиксированы, вообще не пересчитывая граф зависимостей заново — это быстрая и полностью детерминированная операция.

Установка зависимостей строго по зафиксированным в lock-файле версиям
composer install --no-dev --optimize-autoloader

composer update, напротив, игнорирует текущий composer.lock, заново разрешает граф зависимостей на основе диапазонов версий из composer.json (подтягивая самые новые версии, допустимые этими диапазонами) и перезаписывает composer.lock результатом — это ровно та операция, ради которой существует лок-файл, и выполнять её на production-сервере почти никогда не следует.

Полное обновление всех зависимостей и точечное обновление одного пакета
composer update
composer update guzzlehttp/guzzle

Практическое правило простое и без исключений: на этапе разработки, когда нужно осознанно поднять версии зависимостей, используется composer update с последующим тестированием и коммитом обновлённого composer.lock; на production и в CI/CD-пайплайне при каждом деплое выполняется исключительно composer install, которая никогда не должна незапланированно менять версии установленных библиотек.

Автозагрузка классов: как работает PSR-4

Секция autoload в composer.json описывает, как классы проекта сопоставляются с файлами на диске, избавляя от ручных require_once на каждый файл. Стандарт PSR-4 задаёт простое правило: пространству имён (namespace) соответствует директория, и вложенность неймспейса совпадает со вложенностью папок.

Правило PSR-4: класс App\Services\Mailer лежит в файле src/Services/Mailer.php
"autoload": {
    "psr-4": {
        "App\\": "src/"
    }
}

В примере выше класс с полным именем App\Services\Mailer\Mailer автоматически ищется по пути src/Services/Mailer.php — Composer сам сгенерирует нужный код автозагрузчика, и в коде проекта достаточно написать use App\Services\Mailer, чтобы класс подключился без единого явного require.

Пересборка карты автозагрузки с оптимизацией для production
composer dump-autoload -o

Команду composer dump-autoload нужно выполнять вручную только в редких случаях — например, после переименования классов или изменения правил autoload в composer.json без изменения самого списка зависимостей, когда обычный composer install не запускается заново. Флаг -o (то же самое, что --optimize-autoloader) строит статическую карту «класс → файл» вместо динамического разбора правил PSR-4 на каждый запрос, что заметно ускоряет первое обращение к каждому классу под нагрузкой.

Память и таймауты Composer на небольшом VPS

Разрешение графа зависимостей — вычислительно тяжёлая задача, особенно на проектах с десятками пакетов и глубокими цепочками транзитивных зависимостей: Composer перебирает множество комбинаций совместимых версий, прежде чем найти рабочее решение, и на это может потребоваться заметный объём оперативной памяти PHP-процесса.

На VPS с 512 МБ – 1 ГБ оперативной памяти это нередко приводит к падению composer install или composer update с ошибкой нехватки памяти, особенно если на сервере одновременно работают другие сервисы (веб-сервер, база данных), уже занимающие большую часть доступного объёма. Первый и самый надёжный способ обойти проблему — временный своп-файл, дающий процессу запас на время установки без постоянного увеличения потребления диска.

Создание временного файла подкачки на 1 ГБ перед запуском composer install
fallocate -l 1G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

Второй способ — снять с самого Composer ограничение по памяти PHP явно через переменную окружения, не трогая общесистемный memory_limit, который может быть намеренно занижен для остальных PHP-процессов на сервере по соображениям стабильности.

Снятие лимита памяти PHP только для процесса Composer
COMPOSER_MEMORY_LIMIT=-1 composer install --no-dev --optimize-autoloader

Дополнительно стоит убедиться, что на сервере отключено расширение Xdebug на время установки зависимостей — оно значительно замедляет любой PHP-процесс, включая сам Composer, и часто оказывается случайно включённым на сервере, изначально настроенном как окружение для отладки, а не для production. Наконец, для проектов с действительно тяжёлым деревом зависимостей практичнее вообще не запускать composer install на маленьком production-VPS: зависимости устанавливаются на этапе CI/CD-пайплайна на более мощной машине (см. статью про GitHub Actions), а на сервер передаётся уже готовая папка vendor как часть артефакта деплоя.

Безопасность зависимостей: аудит и осторожные обновления

Каждая сторонняя библиотека — это код, которому проект доверяет наравне с собственным, и уязвимость в популярном пакете затрагивает разом все проекты, которые его используют. Начиная с Composer 2.4 в инструмент встроена команда проверки известных уязвимостей в установленных версиях зависимостей.

Проверка установленных зависимостей на известные опубликованные уязвимости
composer audit

Команда сверяет версии пакетов из composer.lock с базой данных известных уязвимостей и выводит список найденных проблем с указанием, в какой версии уязвимость исправлена — эту проверку разумно встроить в CI/CD-пайплайн, чтобы обновление с известной уязвимостью не проходило через пайплайн незамеченным.

Помимо формального аудита, полезны и более простые практики: избегать указания веток вроде dev-master в качестве версии зависимости на production (такая запись может незаметно подтянуть ещё не выпущенный и не протестированный код при обновлении), устанавливать пакеты только с Packagist или из явно указанных доверенных приватных репозиториев, и не бросаться на самую свежую мажорную версию сразу после релиза, дав экосистеме время на обнаружение возможных проблем в первых патч-версиях.

Типичные ошибки при работе с Composer

Коммит папки vendor в Git вместо только composer.json и composer.lock — раздувает репозиторий, замедляет клонирование и создаёт риск несовместимости платформо-зависимых бинарных файлов между окружениями разработчиков и сервером.

Отсутствие composer.lock в репозитории — превращает каждую установку зависимостей в лотерею с неизвестным заранее результатом и лишает всю команду и production-сервер гарантии одинаковых версий библиотек.

Запуск composer update прямо на production-сервере вместо composer install — способен незапланированно подтянуть новые версии зависимостей с изменённым поведением прямо в момент деплоя, минуя любое тестирование.

Использование полностью открытых версий вроде "*" или веток вида dev-master в require — лишает composer.json смысла как декларации совместимых версий и открывает дорогу для установки чего угодно при следующем update.

Игнорирование ошибок несовместимости версии PHP при установке — если composer.json требует php: >=8.2, а на сервере стоит 8.0, Composer честно откажется устанавливать зависимости, и это стоит воспринимать как сигнал обновить PHP, а не пытаться обойти проверку принудительными флагами.

Чек-лист безопасной работы с зависимостями

Шаг 1. Создайте composer.json с явными версионными ограничениями для каждой зависимости (^2.4, а не открытые диапазоны) и укажите минимальную требуемую версию PHP.

Шаг 2. Разделите зависимости на require и require-dev, вынеся инструменты тестирования и отладки в дев-секцию.

Шаг 3. Закоммитьте composer.lock вместе с composer.json, добавив vendor/ в .gitignore.

Шаг 4. На production и в CI/CD используйте только composer install --no-dev --optimize-autoloader, никогда не запускайте update вне этапа осознанного обновления зависимостей.

Шаг 5. На маленьких VPS заранее подготовьте временный своп-файл или переносите готовую vendor как артефакт деплоя вместо установки прямо на сервере.

Шаг 6. Регулярно запускайте composer audit и обновляйте зависимости с известными уязвимостями в приоритетном порядке.

Итог: Composer как основа предсказуемого деплоя PHP-проекта

Composer снимает с разработчика ручное управление совместимостью версий сторонних библиотек и одновременно даёт инструмент для гарантированно одинаковой установки зависимостей на любой машине — при условии, что composer.lock действительно коммитится в репозиторий и на production никогда не запускается update вместо install.

Большая часть проблем с Composer на практике сводится не к самому инструменту, а к нарушению этих двух простых правил: кто-то забыл закоммитить lock-файл, кто-то запустил update прямо на сервере в спешке перед релизом. Соблюдение базовой дисциплины работы с зависимостями избавляет от большинства сюрпризов при деплое.

Если после чтения статьи остаются вопросы по настройке зависимостей конкретного PHP-проекта под ваш VPS — оставьте заявку внизу страницы, поможем разобраться с окружением и настроить процесс деплоя с Composer от начала до конца.

почему мы

Почему стоит выбрать нас

Быстрый запуск

Подберём конфигурацию и развернём проект в день обращения.

Надёжность

NVMe-диски, защита от DDoS и резервные копии по расписанию.

Поддержка 24/7

Дежурные инженеры на связи в любое время суток.

Настройка под ключ

Установим CMS, настроим веб-сервер, SSL и почту за вас.

Перенос без простоя

Аккуратно перенесём сайт и базу данных на новый сервер.

Прозрачные цены

Актуальные тарифы и честный подбор без навязывания.

частые вопросы

Вопросы и ответы

Что произойдёт, если удалить папку vendor целиком?

Ничего страшного — папка vendor не должна храниться в системе контроля версий, она полностью восстанавливается командой composer install на основе файла composer.lock, который и содержит точные версии всех зависимостей.

Нужно ли добавлять vendor в Git?

Нет, стандартная практика — исключить vendor через .gitignore и коммитить только composer.json и composer.lock; сама папка с библиотеками генерируется на каждом окружении заново командой composer install.

Почему composer install зависает или падает с ошибкой памяти на VPS с 512 МБ?

Разрешение графа зависимостей — ресурсоёмкая операция, и на маленьких серверах Composer может упереться в memory_limit PHP; решение — временный своп-файл, переменная COMPOSER_MEMORY_LIMIT=-1 или установка зависимостей на более мощной машине с последующей передачей готовой папки vendor на продакшн.

В чём разница между require и require-dev?

require описывает зависимости, без которых приложение не может работать в production (фреймворк, драйверы БД), а require-dev — инструменты, нужные только разработчику (PHPUnit, PHPStan, отладочные пакеты); на боевом сервере такие пакеты обычно не устанавливаются вовсе.

Как обновить только один конкретный пакет, не трогая остальные?

Командой composer update имя/пакета — Composer пересчитает версию только указанного пакета и его прямых зависимостей, оставив версии остальных библиотек зафиксированными в composer.lock без изменений.

Что делать, если composer.lock конфликтует при слиянии двух веток в Git?

Ручное редактирование composer.lock практически никогда не работает корректно из-за встроенной контрольной суммы файла — правильный путь: разрешить конфликт в composer.json, затем выполнить composer update, чтобы Composer пересобрал lock-файл заново на основе актуальных требований.

Безопасно ли указывать версию зависимости как звёздочку (*)?

Нет, это открывает дорогу для установки абсолютно любой, в том числе будущей несовместимой мажорной версии пакета при следующем composer update — разумнее использовать операторы вроде ^2.4, ограничивающие обновления рамками совместимой мажорной версии.

Стоит ли переходить с Composer 1 на Composer 2, если проект давно работает на первой версии?

Да, Composer 2 заметно быстрее разрешает зависимости и активнее поддерживается разработчиками; Composer 1 официально не получает обновлений безопасности, поэтому продолжение работы на нём — риск для актуальности используемых инструментов установки.

Как оплачивать услуги?

Оплата помесячная, для облачных серверов доступна почасовая тарификация. Принимаются карты, банковские переводы и электронные кошельки.

Есть ли круглосуточная поддержка?

Да, дежурные инженеры на связи 24/7.

Выдаёте ли закрывающие документы?

Да, предоставим необходимые документы для оплаты.

Как оставить заявку?

Заполните форму на странице или нажмите «Заказать» — мы свяжемся и поможем с подбором.

заявка

Оставьте заявку

Ответим и поможем с подбором и настройкой.