Composer: советы по использованию

Composer — это инструмент для управления зависимостями в PHP. Он позволяет нам перечислить библиотеки, от которых зависит наш проект, и будет устанавливать и обновлять их за нас. Мы покажем:

  • как установить Composer
  • его использование в новом или существующем проекте

Установка

Composer — это исполняемый файл .phar, который вы скачиваете и устанавливаете следующим образом:

Windows

Используйте официальный установщик Composer-Setup.exe.

Linux, macOS

Достаточно 4 команд, которые скопируйте с этой страницы.

Далее, поместив в папку, которая находится в системном PATH, Composer станет доступен глобально:

$ mv ./composer.phar ~/bin/composer # или /usr/local/bin/composer

Использование в проекте

Чтобы начать использовать Composer в своем проекте, вам нужен только файл composer.json. Он описывает зависимости нашего проекта и может также содержать другие метаданные. Базовый composer.json может выглядеть так:

{
	"require": {
		"nette/database": "^3.0"
	}
}

Здесь мы говорим, что наше приложение (или библиотека) требует пакет nette/database (название пакета состоит из названия организации и названия проекта) и хочет версию, которая соответствует условию ^3.0 (т. е. последнюю версию 3).

Итак, у нас есть в корне проекта файл composer.json, и мы запускаем установку:

composer update

Composer скачает Nette Database в папку vendor/. Далее он создаст файл composer.lock, который содержит информацию о том, какие именно версии библиотек он установил.

Composer сгенерирует файл vendor/autoload.php, который мы можем просто включить и начать использовать библиотеки без какой-либо дополнительной работы:

require __DIR__ . '/vendor/autoload.php';

$db = new Nette\Database\Connection('sqlite::memory:');

Обновление пакетов до последних версий

За обновление используемых библиотек до последних версий в соответствии с условиями, определенными в composer.json, отвечает команда composer update. Например, для зависимости "nette/database": "^3.0" установит последнюю версию 3.x.x, но не версию 4.

Для обновления условий в файле composer.json, например, до "nette/database": "^4.1", чтобы можно было установить последнюю версию, используйте команду composer require nette/database.

Для обновления всех используемых пакетов Nette потребовалось бы перечислить их все в командной строке, например:

composer require nette/application nette/forms latte/latte tracy/tracy ...

Что непрактично. Используйте поэтому простой скрипт Composer Frontline, который сделает это за вас:

php composer-frontline.php

Создание нового проекта

Новый проект на Nette создается с помощью одной команды:

composer create-project nette/web-project nazev-projekta

В качестве nazev-projekta вставьте название каталога для своего проекта и подтвердите. Composer скачает репозиторий nette/web-project с GitHub, который уже содержит файл composer.json, и сразу после этого Nette Framework. Должно уже хватить только установить права на запись в папки temp/ и log/, и проект должен ожить.

Если вы знаете, на какой версии PHP будет хоститься проект, не забудьте ее установить.

Версия PHP

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

То, что проект будет работать, например, на PHP 8.2.3, мы установим командой:

composer config platform.php 8.2.3

Так версия запишется в файл composer.json:

{
	"config": {
		"platform": {
			"php": "8.2.3"
		}
	}
}

Однако номер версии PHP указывается еще в другом месте файла, а именно в секции require. В то время как первое число определяет, для какой версии будут устанавливаться пакеты, второе число говорит, для какой версии написано само приложение. И по нему, например, PhpStorm устанавливает PHP language level. (Конечно, нет смысла, чтобы эти версии различались, так что двойная запись — это недоработка.) Эту версию вы установите командой:

composer require php 8.2.3 --no-update

Или прямо в файле composer.json:

{
	"require": {
		"php": "8.2.3"
	}
}

Игнорирование версии PHP

Пакеты обычно указывают как самую низкую версию PHP, с которой они совместимы, так и самую высокую, с которой они протестированы. Если вы собираетесь использовать версию PHP еще новее, например, для тестирования, Composer откажется устанавливать такой пакет. Решением является опция --ignore-platform-req=php+, которая заставит Composer игнорировать верхние пределы требуемой версии PHP.

Ложные сообщения

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

Если сообщение об ошибке сохраняется, то оно серьезное, и нужно из него понять, что и как исправить.

Packagist.org – центральный репозиторий

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

Что делать, если мы не хотим использовать центральный репозиторий?

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

Больше на тему репозиториев в официальной документации.

Автозагрузка

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

Однако можно использовать Composer и для загрузки других классов и вне папки vendor. Первой возможностью является позволить Composer просканировать определенные папки и подпапки, найти все классы и включить их в автозагрузчик. Этого можно достичь, установив autoload > classmap в composer.json:

{
	"autoload": {
		"classmap": [
			"src/",      #  включит папку src/ и ее подпапки
		]
	}
}

Затем необходимо при каждом изменении запускать команду composer dumpautoload и позволить перегенерировать таблицы автозагрузки. Это крайне неудобно, и гораздо лучше доверить эту задачу RobotLoader, который ту же самую деятельность выполняет автоматически в фоновом режиме и гораздо быстрее.

Второй возможностью является соблюдение PSR-4. Упрощенно говоря, это система, когда пространства имен и названия классов соответствуют структуре каталогов и названиям файлов, то есть, например, App\Core\RouterFactory будет в файле /path/to/App/Core/RouterFactory.php. Пример конфигурации:

{
	"autoload": {
		"psr-4": {
			"App\\": "app/"   # пространство имен App\ находится в каталоге app/
		}
	}
}

Как точно настроить поведение, вы узнаете в документации Composer.

Тестирование новых версий

Хотите протестировать новую разработочную версию пакета? Как это сделать? Сначала в файл composer.json добавьте эту пару опций, которая позволит устанавливать разработочные версии пакетов, однако прибегнет к этому только в случае, если не существует никакой комбинации стабильных версий, которая бы удовлетворяла требованиям:

{
	"minimum-stability": "dev",
	"prefer-stable": true,
}

Далее рекомендуем удалить файл composer.lock, иногда Composer необъяснимо отказывается от установки, и это решает проблему.

Допустим, это пакет nette/utils, и новая версия имеет номер 4.0. Установите ее командой:

composer require nette/utils:4.0.x-dev

Или вы можете установить конкретную версию, например, 4.0.0-RC2:

composer require nette/utils:4.0.0-RC2

Но если от библиотеки зависит другой пакет, который заблокирован на старой версии (например, ^3.1), то идеально обновить пакет, чтобы он работал с новой версией. Однако, если вы хотите просто обойти ограничение и заставить Composer установить разработочную версию и притвориться, что это старая версия (например, 3.1.6), вы можете использовать ключевое слово as:

composer require nette/utils "4.0.x-dev as 3.1.6"

Вызов команд

Через Composer можно вызывать собственные предопределенные команды и скрипты, как если бы это были нативные команды Composer. Для скриптов, которые находятся в папке vendor/bin, не нужно указывать эту папку.

В качестве примера определим в файле composer.json скрипт, который с помощью Nette Tester запустит тесты:

{
	"scripts": {
		"tester": "tester tests -s"
	}
}

Тесты затем запустим с помощью composer tester. Команду можно вызвать и в случае, если мы не находимся в корневой папке проекта, а в каком-либо подкаталоге.

Отправьте благодарность

Покажем вам трюк, которым вы порадуете авторов open source. Простым способом поставите на GitHub звездочку библиотекам, которые использует ваш проект. Достаточно установить библиотеку symfony/thanks:

composer global require symfony/thanks

А затем запустить:

composer thanks

Попробуйте!

Конфигурация

Composer тесно связан с инструментом версионирования Git. Если он у вас не установлен, нужно сказать Composer, чтобы он его не использовал:

composer -g config preferred-install dist