Composer.json в PHP: полный разбор инструмента управления зависимостями
Работа с composer.json: управление зависимостями PHP
Файл composer.json является центральным элементом управления зависимостями в PHP-проектах. В нем описываются требования к пакетам, конфигурация автозагрузки, скрипты и многие другие параметры. Ниже рассмотрено основное решение (базовое описание) и несколько вариантов настройки с пояснениями целей и типичных проблем.
Как создать минимальный composer.json для проекта?
Основная цель: определить имя проекта, описание, требуемые пакеты и способ автозагрузки классов.
{
"name": "myvendor/myapp",
"description": "Пример приложения",
"require": {
"php": ">=8.0",
"monolog/monolog": "^2.0"
},
"autoload": {
"psr-4": {
"MyApp\\": "src/"
}
}
}Docker php composer (composer в docker php)
После создания файла выполняется composer install. Пакет Monolog загружается в vendor, автозагрузка настраивается по PSR-4. Возникающая проблема: если не указать автозагрузку, классы не будут находиться – в логах появится ошибка Class not found.
Почему после добавления пакета класс не находится?
Ошибка чаще всего связана с несоответствием namespace в коде и пути в autoload. Например, если неймспейс MyApp\ а файл лежит в src/Models, но класс называется MyApp\Models\User – автозагрузка сработает, только если директория Models существует внутри src. Если же структура другая, нужно либо менять autoload на classmap, либо добавлять в autoload несколько префиксов.
Как указать зависимость только для разработки?
Цель: установить пакеты для тестирования, code style, PHPStan, которые не нужны на production.
{
"require-dev": {
"phpunit/phpunit": "^10.0",
"phpstan/phpstan": "^1.10"
}
}Autoload php composer (автозагрузка классов с помощью composer в php)
Установка производится командой composer install --no-dev на продакшне. Типичная ошибка: использование класса из dev-пакета в основном коде – на продакшне вызовет фатальную ошибку.
Как настроить автозагрузку по PSR-0?
Цель: поддержка устаревших библиотек, использующих PSR-0.
{
"autoload": {
"psr-0": {
"MyLib_": "src/"
}
}
}Php composer package (управление пакетами composer в php)
Проблема: PSR-0 требует имена классов с подчеркиваниями, что не соответствует современным стандартам. При переходе на PSR-4 может потребоваться рефакторинг.
Как добавить пользовательский репозиторий?
Цель: установить пакет не из Packagist, а из приватного Git-репозитория или локальной папки.
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/mycompany/mylib"
},
{
"type": "path",
"url": "../mylib-local",
"options": {
"symlink": true
}
}
]
}Composer php 8.1 (установка composer для php 8.1)
После добавления репозитория можно указать пакет mycompany/mylib в require. Ошибка: если версия в репозитории не соответствует require (например, не указан тег), composer выдаст предупреждение о неверном формате версии.
Как зафиксировать минимальную стабильность?
Цель: разрешить или запретить установку нестабильных версий (dev, alpha, beta).
{
"minimum-stability": "stable",
"prefer-stable": true
}Php composer json (php: работа с composer.json)
Если разработчик хочет использовать dev-версию конкретного пакета, можно указать её явно в require: "monolog/monolog": "dev-main". Проблема: при minimum-stability: stable и отсутствии prefer-stable, composer может не установить пакет, если его стабильная версия не найдена – в итоге ошибка Could not find a matching version.
Как задать платформенные требования (версию PHP, расширения)?
Цель: гарантировать, что на целевой машине установлена нужная версия PHP и расширения.
{
"require": {
"php": ">=8.0, <8.3",
"ext-json": "*",
"ext-mbstring": "*"
},
"config": {
"platform": {
"php": "8.1"
}
}
}Composer platform php (платформа composer (platform config))
Ключ config.platform позволяет имитировать определённую платформу для разрешения зависимостей (полезно, когда разработка ведётся на PHP 8.2, а продакшн на 8.1). Типичная ошибка: указание в platform версии, которая не совпадает с фактической, – тогда установленные пакеты могут использовать функции, недоступные в реальной среде.
Как управлять скриптами (hooks)?
Цель: выполнять автоматические действия после определённых событий (install, update, autoload-dump).
{
"scripts": {
"post-install-cmd": [
"@clear-cache",
"php artisan config:cache"
],
"post-update-cmd": [
"@clear-cache"
],
"clear-cache": "rm -rf var/cache/*"
}
}Vendor php (директория vendor в php (composer))
Проблема: если скрипт завершается с ошибкой, composer прерывает выполнение. Для отладки можно использовать @composer --verbose.
Как обработать конфликтующие пакеты?
Цель: предотвратить установку несовместимых библиотек.
{
"conflict": {
"vendor/package": ">=2.0",
"vendor/old-lib": "*"
}
}
Ошибка: если конфликтующая версия уже установлена, composer при попытке обновления выдаст сообщение The requested package conflicts with ....
Расширенные примеры работы с composer.json
Как создать псевдоним для репозитория, чтобы переопределить версию пакета?
Цель: использование частного форка с другой версией вместо оригинального пакета.
{
"repositories": [
{
"type": "package",
"package": {
"name": "monolog/monolog",
"version": "2.9.0",
"source": {
"url": "https://github.com/myfork/monolog",
"type": "git",
"reference": "ac1e5e5f"
}
}
}
]
}
Результат: composer install скачает именно этот форк, игнорируя packagist.
Важно: такой подход создаёт изолированную среду, но при обновлении нужно менять reference вручную.
Как добавить кастомный установщик для нестандартных типов пакетов?
Цель: устанавливать пакеты в произвольную директорию, а не в vendor.
{
"require": {
"composer/installers": "^1.0"
},
"extra": {
"installer-paths": {
"themes/{$name}/": ["type:wordpress-theme"],
"plugins/{$name}/": ["type:wordpress-plugin"]
}
}
}
После установки любой пакет с типом "wordpress-theme" будет помещён в themes/имя_пакета/.
Ошибка: если не указать composer/installers, кастомные пути работать не будут – composer использует только свою стандартную установку в vendor.
Как использовать platform.php для имитации более низкой версии PHP, чем установлена?
Цель: гарантировать совместимость с минимальной версией.
{
"config": {
"platform": {
"php": "8.0.0"
},
"platform-check": false
},
"require": {
"php": ">=8.0.0"
}
}
composer update будет подбирать версии пакетов так, как будто PHP - 8.0, даже если локально 8.2.
Проблема: если в коде используются фичи PHP 8.1 (например, Fibers), composer это не отследит – нужно дополнительно проверять статическим анализом.
Как настроить автоматическую оптимизацию автозагрузчика для production?
Цель: ускорить загрузку классов, генерируя classmap или OPcache-friendly файл.
{
"config": {
"optimize-autoloader": true,
"classmap-authoritative": true,
"apcu-autoloader": true
}
}
После composer install --no-dev --optimize-autoloader будет сгенерирован classmap, а автозагрузчик не будет проверять файловую систему – только classmap.
Важно: при добавлении нового класса нужно перегенерировать autoload (composer dump-autoload -o).
Как добавить запрещённые (banned) пакеты в composer.json?
Цель: предотвратить установку уязвимых или устаревших пакетов.
{
"conflict": {
"vendor/unsafe-package": "*",
"vendor/old-package": "<=1.0.0"
}
}
Если кто-то попытается добавить "vendor/old-package" в require, composer выдаст ошибку конфликта.
Рекомендуется использовать composer audit для проверки известных уязвимостей, а не только conflict.
Как создать composer.json для библиотеки с несколькими автозагрузками (PSR-4 + classmap)?
Цель: обеспечить автозагрузку как современных PSR-4 классов, так и устаревших глобальных функций.
{
"autoload": {
"psr-4": {
"MyApp\\": "src/"
},
"classmap": [
"legacy/"
],
"files": [
"src/helpers.php"
]
}
}
Файлы в legacy/ будут просканированы один раз (при dump-autoload), а helpers.php будет загружаться всегда.
Ошибка: если legacy-класс дублирует namespace из PSR-4, возможен конфликт – composer выдаст предупреждение. Лучше избегать пересечений.