Что такое Composer и зачем он нужен
Composer — это менеджер зависимостей для PHP. Он позволяет объявлять библиотеки, от которых зависит ваш проект, и управлять их установкой и обновлением. Composer работает на уровне проекта (не глобально, как системные пакетные менеджеры), устанавливая пакеты в директорию vendor/ внутри проекта.
Ключевые задачи Composer:
- Управление зависимостями — автоматическая установка и обновление библиотек
- Автозагрузка классов — единый автозагрузчик для всего проекта (PSR-4, PSR-0, classmap, files)
- Скрипты — автоматизация рутинных задач (проверка кода, очистка кэша)
- Управление версиями — семантическое версионирование и фиксация зависимостей
До Composer PHP-разработчики вручную скачивали библиотеки, копировали файлы, подключали через require/include. Это приводило к конфликтам версий, дублированию кода и невоспроизводимым сборкам.
Установка Composer
Глобальная установка (рекомендуется для локальной разработки)
# Download installer
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
# Verify installer hash (always check getcomposer.org/download for current hash)
php -r "if (hash_file('sha384', 'composer-setup.php') === 'EXPECTED_HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
# Install globally
php composer-setup.php --install-dir=/usr/local/bin --filename=composer
# Cleanup
php -r "unlink('composer-setup.php');"
# Verify installation
composer --version
Установка через Docker (рекомендуется для проектов)
# In your Dockerfile
FROM php:8.4-fpm
# Install Composer from official image
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Set working directory
WORKDIR /app
# Copy dependency files first (layer caching)
COPY composer.json composer.lock ./
# Install dependencies
RUN composer install --no-dev --optimize-autoloader --no-scripts
# docker-compose.yml
services:
php:
build: .
volumes:
- .:/app
# Usage:
# docker compose exec php composer require monolog/monolog
# docker compose exec php composer install
Локальная установка (per-project)
# Install Composer locally in the project
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
# Use with php prefix
php composer.phar install
Структура composer.json
Файл composer.json — это сердце Composer. Он описывает проект и его зависимости.
Полный пример composer.json
{
"name": "mycompany/my-project",
"description": "Description of the project",
"type": "project",
"license": "MIT",
"authors": [
{
"name": "John Doe",
"email": "[email protected]"
}
],
"minimum-stability": "stable",
"prefer-stable": true,
"require": {
"php": ">=8.4",
"symfony/framework-bundle": "^7.2",
"doctrine/orm": "^3.3",
"monolog/monolog": "^3.8"
},
"require-dev": {
"phpunit/phpunit": "^11.5",
"phpstan/phpstan": "^2.1",
"friendsofphp/php-cs-fixer": "^3.68"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/"
}
},
"scripts": {
"test": "phpunit",
"analyse": "phpstan analyse",
"cs-fix": "php-cs-fixer fix",
"check": [
"@analyse",
"@test"
],
"post-install-cmd": [
"@auto-scripts"
],
"post-update-cmd": [
"@auto-scripts"
]
},
"config": {
"optimize-autoloader": true,
"sort-packages": true,
"allow-plugins": {
"symfony/flex": true
}
}
}
Разбор ключевых полей
name — уникальное имя пакета в формате vendor/package. Обязательно для публикуемых пакетов.
type — тип пакета:
library(по умолчанию) — обычная библиотекаproject— приложениеmetapackage— пустой пакет, объединяющий зависимостиcomposer-plugin— плагин для Composer
minimum-stability — минимально допустимая стабильность пакетов: dev, alpha, beta, RC, stable (по умолчанию).
prefer-stable — при установке Composer предпочтёт стабильную версию, даже если minimum-stability разрешает нестабильные.
require — зависимости для production. Устанавливаются всегда.
require-dev — зависимости для разработки (тесты, линтеры, отладка). Не устанавливаются с флагом --no-dev.
composer.lock — зачем нужен
Файл composer.lock фиксирует точные версии всех установленных пакетов (включая транзитивные зависимости). Это гарантирует воспроизводимость сборки.
Когда коммитить composer.lock
| Тип проекта | Коммитить lock? | Почему |
|---|---|---|
| Приложение (project) | Да, всегда | Все разработчики и CI получают одинаковые версии |
| Библиотека (library) | Нет | Потребители библиотеки должны самостоятельно разрешать зависимости |
# .gitignore for a library
/vendor/
composer.lock
# .gitignore for a project
/vendor/
# composer.lock — NOT in gitignore!
Как работает lock-файл
# First install: resolves versions, creates lock file
composer install
# Creates: composer.lock with exact versions
# Subsequent installs: reads lock file, installs exact versions
composer install
# Reads: composer.lock, ignores version constraints from composer.json
# Update: re-resolves versions, updates lock file
composer update
# Updates: composer.lock with new resolved versions
Основные команды Composer
Инициализация проекта
# Interactive project initialization
composer init
# Will ask:
# - Package name (vendor/name)
# - Description
# - Author
# - Minimum Stability
# - Package Type
# - License
# - Dependencies (require)
# - Dev dependencies (require-dev)
Управление зависимостями
# Add a production dependency
composer require monolog/monolog
# Add a specific version
composer require monolog/monolog:^3.0
# Add a development dependency
composer require --dev phpunit/phpunit
# Remove a dependency
composer remove monolog/monolog
# Install all dependencies from lock file
composer install
# Install without dev dependencies (production)
composer install --no-dev
# Update all dependencies
composer update
# Update specific package
composer update monolog/monolog
# Update with all transitive dependencies
composer update --with-all-dependencies
Информационные команды
# Show installed packages
composer show
# Show details of a specific package
composer show monolog/monolog
# Show installed packages as a tree
composer show --tree
# Show outdated packages
composer outdated
# Show direct outdated dependencies only
composer outdated --direct
# Why is a package installed?
composer why monolog/monolog
# Why can't a package be installed?
composer why-not monolog/monolog 4.0
# Validate composer.json
composer validate
# Validate with strict mode
composer validate --strict
Автозагрузка
# Regenerate autoloader
composer dump-autoload
# Optimized autoloader (generates classmap)
composer dump-autoload --optimize
# Classmap-authoritative (only loads from classmap)
composer dump-autoload --classmap-authoritative
Семантическое версионирование (SemVer)
Composer использует семантическое версионирование (SemVer) для определения совместимости пакетов.
Формат версии: MAJOR.MINOR.PATCH
- MAJOR (1.x.x → 2.x.x) — несовместимые изменения API
- MINOR (1.1.x → 1.2.x) — новый функционал, обратная совместимость сохранена
- PATCH (1.1.1 → 1.1.2) — исправления багов, обратная совместимость сохранена
Операторы версий в Composer
{
"require": {
"vendor/package-a": "1.2.3",
"vendor/package-b": ">=1.2",
"vendor/package-c": ">=1.2 <2.0",
"vendor/package-d": "~1.2.3",
"vendor/package-e": "^1.2.3",
"vendor/package-f": "1.2.*",
"vendor/package-g": "^0.3.0",
"vendor/package-h": "dev-main"
}
}
Подробный разбор операторов
| Оператор | Пример | Эквивалент | Описание |
|---|---|---|---|
| Точная версия | 1.2.3 |
=1.2.3 |
Только эта версия |
>= |
>=1.2 |
>=1.2.0 |
Эта версия и выше |
| Диапазон | >=1.2 <2.0 |
— | Между версиями |
~ (тильда) |
~1.2.3 |
>=1.2.3 <1.3.0 |
Последняя цифра может расти |
^ (каретка) |
^1.2.3 |
>=1.2.3 <2.0.0 |
Совместимые с SemVer |
* (wildcard) |
1.2.* |
>=1.2.0 <1.3.0 |
Любой patch |
^0.x |
^0.3.0 |
>=0.3.0 <0.4.0 |
Для pre-1.0 пакетов |
Самый важный оператор — ^ (каретка). Он разрешает все обратно совместимые обновления. Это рекомендуемый оператор для большинства случаев.
{
"require": {
"^1.2.3": "allows 1.2.3, 1.2.4, 1.3.0, 1.9.99 — but NOT 2.0.0",
"~1.2.3": "allows 1.2.3, 1.2.4, 1.2.99 — but NOT 1.3.0",
"^0.3.0": "allows 0.3.0, 0.3.1, 0.3.99 — but NOT 0.4.0 (pre-1.0 special)"
}
}
composer install vs composer update — КРИТИЧЕСКАЯ РАЗНИЦА
Это одна из самых частых ошибок новичков. Разница принципиальна:
composer install
composer install
- Читает
composer.lock - Устанавливает точные версии из lock-файла
- Если
composer.lockотсутствует — работает какcomposer update(создаёт lock)
Когда использовать: В CI/CD, на production, при клонировании проекта, при первой настройке окружения.
composer update
composer update
- Читает
composer.json - Разрешает зависимости заново
- Устанавливает новейшие подходящие версии
- Обновляет
composer.lock
Когда использовать: Когда хотите обновить зависимости. Только на машине разработчика, с последующим тестированием.
Наглядная разница
# SCENARIO: composer.json has "monolog/monolog": "^3.0"
# composer.lock has monolog/monolog 3.5.0
# Latest available: monolog/monolog 3.8.1
# composer install → installs 3.5.0 (from lock)
# composer update → installs 3.8.1 (resolves from json, updates lock)
# CRITICAL CI/CD MISTAKE:
# ❌ WRONG: using "composer update" in CI/CD pipeline
# ✅ RIGHT: using "composer install --no-dev --optimize-autoloader"
Типичный рабочий процесс
# Developer wants to add a package:
composer require guzzlehttp/guzzle
# Developer wants to update packages:
composer update
# Review changes, run tests
# Commit updated composer.lock
# CI/CD pipeline:
composer install --no-dev --optimize-autoloader --no-interaction
# Another developer joins the team:
git clone project
composer install
# Gets exact same versions as everyone else
Автозагрузка PSR-4
PSR-4 — стандарт автозагрузки, который связывает пространства имён (namespaces) с директориями файловой системы.
Настройка PSR-4 в composer.json
{
"autoload": {
"psr-4": {
"App\\": "src/",
"App\\Infrastructure\\": "infrastructure/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/"
}
}
}
Правила маппинга
Namespace prefix маппится на директорию. Класс App\Service\UserService ищется в файле src/Service/UserService.php.
Namespace: App\Entity\User
Mapping: App\ → src/
File: src/Entity/User.php
Namespace: App\Tests\Service\UserServiceTest
Mapping: App\Tests\ → tests/
File: tests/Service/UserServiceTest.php
Структура проекта
project/
├── composer.json
├── composer.lock
├── vendor/
│ └── autoload.php # Generated autoloader
├── src/
│ ├── Entity/
│ │ └── User.php # App\Entity\User
│ ├── Service/
│ │ └── UserService.php # App\Service\UserService
│ └── Controller/
│ └── HomeController.php # App\Controller\HomeController
└── tests/
└── Service/
└── UserServiceTest.php # App\Tests\Service\UserServiceTest
Использование автозагрузчика
<?php
declare(strict_types=1);
// Include Composer's autoloader — single entry point for all classes
require_once __DIR__ . '/vendor/autoload.php';
use App\Service\UserService;
use App\Entity\User;
// Classes are automatically loaded, no manual require needed
$service = new UserService();
$user = new User(name: 'John', email: '[email protected]');
autoload-dev для тестов
Секция autoload-dev загружается только при composer install (не с --no-dev). Это позволяет разделить production и test автозагрузку.
{
"autoload": {
"psr-4": {
"App\\": "src/"
},
"files": [
"src/helpers.php"
]
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/",
"App\\DataFixtures\\": "fixtures/"
}
}
}
После изменения autoload необходимо перегенерировать автозагрузчик:
composer dump-autoload
Скрипты в composer.json
Скрипты позволяют автоматизировать задачи при определённых событиях Composer или запускать их вручную.
Встроенные события
{
"scripts": {
"pre-install-cmd": "echo 'About to install dependencies'",
"post-install-cmd": [
"@php bin/console cache:clear",
"@php bin/console assets:install"
],
"post-update-cmd": [
"@php bin/console cache:clear"
],
"pre-autoload-dump": "echo 'About to regenerate autoloader'",
"post-autoload-dump": [
"App\\ScriptHandler::postAutoloadDump"
]
}
}
Пользовательские скрипты
{
"scripts": {
"test": "phpunit --colors=always",
"test:coverage": "phpunit --coverage-html coverage/",
"analyse": "phpstan analyse --memory-limit=512M",
"cs-fix": "php-cs-fixer fix",
"cs-check": "php-cs-fixer fix --dry-run --diff",
"check": [
"@cs-check",
"@analyse",
"@test"
],
"build": [
"@composer install --no-dev --optimize-autoloader",
"@php bin/console cache:warmup"
]
}
}
# Run custom scripts
composer test
composer analyse
composer check
composer build
Packagist и приватные репозитории
Packagist.org
Packagist — основной публичный репозиторий для PHP-пакетов. По умолчанию Composer ищет пакеты именно здесь.
# Search for packages
composer search monolog
# Show package info from Packagist
composer show monolog/monolog --all
Приватные пакеты
Для проприетарного кода используются приватные репозитории.
VCS Repository (Git):
{
"repositories": [
{
"type": "vcs",
"url": "[email protected]:mycompany/private-package.git"
}
],
"require": {
"mycompany/private-package": "^1.0"
}
}
Satis (self-hosted Packagist):
{
"repositories": [
{
"type": "composer",
"url": "https://satis.mycompany.com"
}
]
}
Private Packagist (SaaS):
{
"repositories": [
{
"type": "composer",
"url": "https://repo.packagist.com/mycompany/"
}
]
}
Практические примеры
Создание нового Symfony-проекта
# Create new Symfony project
composer create-project symfony/skeleton my-project
cd my-project
# Add commonly used packages
composer require symfony/orm-pack
composer require symfony/maker-bundle --dev
composer require symfony/debug-bundle --dev
# Add testing tools
composer require --dev phpunit/phpunit
composer require --dev phpstan/phpstan
composer require --dev phpstan/phpstan-symfony
# Validate configuration
composer validate --strict
# Show dependency tree
composer show --tree
Создание нового Laravel-проекта
# Create new Laravel project
composer create-project laravel/laravel my-laravel-app
cd my-laravel-app
# Add packages
composer require laravel/sanctum
composer require spatie/laravel-permission
# Add dev tools
composer require --dev larastan/larastan
composer require --dev laravel/pint
# Check for outdated packages
composer outdated --direct
Типичный рабочий процесс в команде
# Developer A adds a new package
composer require league/flysystem
# Commit both composer.json and composer.lock
# Developer B pulls changes
git pull
composer install
# Gets exact same version of league/flysystem
# Weekly dependency update
composer outdated --direct
composer update --with-all-dependencies
# Run full test suite
composer test
# If tests pass, commit updated lock file