В чем разница между composer.json и composer.lock в PHP?

Ответ

composer.json — это декларативный файл конфигурации, где разработчик вручную определяет зависимости проекта и их примерные версии с использованием семантического версионирования (например, "symfony/console": "^5.0").

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

Ключевое отличие:

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

Пример:

// composer.json
{
    "require": {
        "laravel/framework": "^10.0"
    }
}

// composer.lock (сокращённо)
{
    "packages": [
        {
            "name": "laravel/framework",
            "version": "10.45.1",
            "source": {
                "reference": "a1b2c3d4e5"
            }
        }
    ]
}

Практика: Оба файла следует коммитить в систему контроля версий (Git). Это гарантирует, что все члены команды и production-сервер используют идентичные версии зависимостей. При развёртывании на продакшене используется composer install --no-dev, который читает версии из composer.lock.

Ответ 18+ 🔞

А, ну это же классика, про которую каждый второй спотыкается, когда только начинает с Composer'ом работать! Сейчас разложу по полочкам, чтобы ты сам от себя охуел, как всё просто.

Представь, что composer.json — это твой список покупок в магазин. Ты пишешь там: «Мне нужен хлеб, молоко, и, скажем, колбаса какой-нибудь». То есть, ты определяешь, какие пакеты (laravel/framework) и в каком примерно диапазоне (^10.0) тебе нужны. Это твои хотелки.

А теперь смотри сюда. Ты приходишь в магазин, а там хлеб — он же чёрт знает какой: «Бородинский», «Дарницкий», вчерашний, сегодняшний. Если бы каждый раз, когда ты или твой кореш идёте в магазин с одним и тем же списком, вы приносили разный хлеб — это был бы пиздец. Начались бы крики: «А у меня на локалке работало, а на продакшене — хуй с горы!».

Вот для этого и существует composer.lock. Это твой фискальный чек. После того как ты в первый раз выполнил composer install, Composer сходит в магазин, выберет конкретные версии всего, что нужно (включая зависимости этих зависимостей — там же ёперный театр иногда начинается!), и зафиксирует это в composer.lock. Он запишет не просто «хлеб», а «Хлеб Бородинский, вес 500г, артикул 148822, испечён 12.05, цена 50 рублей».

Итог простой, как три копейки:

  • composer.json — говорит, что нам нужно.
  • composer.lock — говорит, какая именно версия этого «чего-то» у нас сейчас лежит и работает.

А теперь главный лайфхак, из-за незнания которого доверия к некоторым коллегам — ноль ебать. Оба файла — composer.json И composer.lock — нужно коммитить в Git!

Почему? Да потому что когда твой тимлид, или CI/CD пайплайн, или продакшен-сервер делает composer install, он смотрит в первую очередь в composer.lock. И устанавливает точно те же версии, что и у тебя. Никаких сюрпризов. Всё воспроизводимо. Полная идиллия.

А если ты хочешь обновить зависимости — ты сознательно делаешь composer update. Тогда Composer перечитает composer.json, найдёт новые подходящие версии в рамках твоих правил, установит их и перезапишет composer.lock новыми, конкретными версиями. И этот обновлённый лок-файл ты тоже коммитишь. Всё, волнение ебать — у команды снова одинаковые версии, только посвежее.

Короче, запомни как «Отче наш»: json — желания, lock — реальность. Коммить оба, и живи спокойно.