Логотип
Разработчикам

Почему PHP Composer – это больше, чем просто менеджер зависимостей

Павел Гапоненко

Backend-разработчик

В настоящее время сложно представить проект без менеджера зависимостей, независимо от того, на каком языке программирования он написан. Для PHP таким менеджером является Composer.

Цель данной статьи – не только познакомить вас с пакетным менеджером Composer, но и рассказать немного больше, чем просто о способах установки и обновления сторонних пакетов.

Что такое Composer?

Composer - это инструмент для управления сторонними библиотеками в PHP-проекте. Он позволяет подключать, устанавливать и обновлять библиотеки или «пакеты», а также управлять их версиями.

Разработка Composer была вдохновлена уже существующими на тот момент менеджерами пакетов: npm (Node.js) и bundler (Ruby). Первый релиз состоялся 1 марта 2012 года.

Это кроссплатформенный инструмент: он одинаково работает на операционных системах Windows, Linux и OSX.

Чем Composer отличается от Pear

До появления Composer в мире PHP-разработки существовал PEAR (PHP Extension and Application Repository) – это фреймворк и система распространения повторно используемых PHP-компонентов.

Дело в том, что у PEAR есть несколько существенных минусов:

  1. Библиотека устанавливается в масштабе всей системы, а не для каждого проекта отдельно, таким образом, невозможно использовать несколько разных версий одной библиотеки на компьютере.
  2. Чтобы загрузить библиотеку в PEAR, необходимо набрать определенное количество голосов.
  3. Существующие решения были часто устаревшими, неактивными или неподдерживающимися.

Основы использования Composer

Простое управление библиотеками и пакетами в PHP-проекте.

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

init – инициализация проекта (а зачастую она не требуется при использовании PHP-фреймворка);

require – подключить пакет;

install – установить зависимости;

update – обновить пакеты;

При использовании этих команд можно легко продолжить работу над проектом, не вдаваясь в подробности. Также есть подробная официальная документация, там можно прочесть всю необходимую информацию по установке и использованию.

Но Composer – это больше, чем просто пакетный менеджер. Чтобы в этом разобраться, для начала пройдемся по основам использования:

Composer.json

Центральный файл для управления – composer.json. В нем описываются различные настройки и, самое главное, пакеты, от которых зависит наш проект:

В блоке require указываются необходимые нам пакеты, но их также можно добавить и с помощью команды:

Версии пакетов

Большинство разработчиков при разработке своих пакетов следуют соглашению SemVer – семантическое версионирование. Это соглашение, при котором номер версии указывается в следующем виде:

| MAJOR.MINOR.PATCH,

где MAJOR, MINOR и PATСH - целые числа, начиная с 0.

Когда следует увеличивать версию:

  • Major (мажорная версия) - обратно несовместимые изменения в API.
  • Minor (минорная версия) - добавлена функциональность и при этом не нарушена обратная совместимость.
  • Patch (патч-версия) - баг-фиксы, незначительные доработки.

Некоторые способы указания версий в composer.json:

*Точная версия*

"worksolutions/php-collections""1.1.7"

*Диапазон версий*

"worksolutions/php-collections"">=1.0.0"

*Диапазон тильды*

"worksolutions/php-collections""~1.2.3"

Эквивалентно >=1.2.3 <1.3.0

*Диапазон каретки*

"worksolutions/php-collections""^1.2.3"

Эквивалентно >=1.2.3 <2.0.0. Используется для ограничения мажорной версии, чтобы гарантировать обратную совместимость

*Диапазон версий подстановочных знаков*

"worksolutions/php-collections": *"1.0.\"**

Эквивалентно >=1.0.0 <1.1

Также, в качестве версии можно указать название ветки или хэш коммита, если в качестве поставщика пакета используется git-репозиторий.

Файл блокировки

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

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

Рекомендуется сохранять файл composer.lock в системе контроля версий.

Основные команды

Инициализация проекта

$composer init

Установка пакетов

$composer install

При первом запуске будет взята информация из файла composer.json, затем создается файл composer.lock, на основе которого и происходит установка.

Обновление

$composer update

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

Обновление

$composer require

Добавит пакет в composer.json

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

Чтобы использовать классы проекта или установленных библиотек, необходимо подключить сгенерированный файл:

Пример autoload в файле composer.json:

![Изображение статьи](https://lh6.googleusercontent.com/2_meBu8Wf70RqqpECIZJUjPzqEktH9dC4pBRZV3H1AaOJJA6ApMQjX7v4OXEWQj063LPBhlxttfuMziUVOgiAnBWhLt2y6W3laUTaI-QelzoJ3tk7UFFuY31GkpHZwxZ51ugn1eirpO5pzmFO9qiM5Q)

Данную запись можно понимать следующим образом: класс, который имеет путь src/Service/Logger.php будет иметь пространство имен App\Service.

Подключить данный класс можно с использованием директивы use:

Пакеты

Каждый проект по сути является пакетом. С разницей лишь в том, что название библиотеки обязательное, а проекта нет.

Способы подключения

Существует немало различных способов подключить библиотеку в проект. Так, библиотеку можно подключить, если она доступна через VCS (систему контроля версий), либо использовать прямую ссылку на zip-файл с пакетом.

Подключение пакетов, опубликованных на Packagist, удобный, простой и распространенный метод.

Рассмотрим подключение библиотеки PHP-коллекций через git-репозиторий:

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

Данный способ выглядит несложным, однако, проще подключать библиотеки, которые хранятся на Packagist. Рассмотрим пример подключения той же библиотеки, но через Packagist:

Репозиторий Packagist не нужно специально указывать в Composer - он зарегистрирован там по-умолчанию.

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

Создание репозитория

Перед тем, как начать разработку нашего пакета, создадим репозиторий на GitHub:

Клонируем репозиторий и переходим в папку проекта

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

Инициализация проекта

Генерируем конфигурационный файл, выполнив команду инициализации

![Изображение статьи](https://lh5.googleusercontent.com/BDnom_s6BT8U5d3qw4fwiYCsog-pf2I2IIpm8kRqi8mwT2Z3Ln8MISvbZSXP2xI4UqoZgAFy-U60FSapRQKZTGA4HcxKaBRZK3W2LjZxhkG1_YHT4WCzbpWK_0NpFYy9ww4hKW45sdzYVo93NuK0ORo)

Далее отвечаем на вопросы, именуем пакет в формате <vendor>/<name>, где vendor - имя автора, например, имя пользователя на Github, name - имя пакета.

Тип указываем library, без указания, на данном этапе, дополнительных пакетов.

В итоге при завершении работы команды будет создан файл composer.json:

Создание файла README

Рекомендуется в файле README.md указать:

  • Название
  • Доступную версию PHP
  • Способ установки
  • Примеры использования

Версионирование

Версии пакета добавляются с помощью команды git tag.

Пример:

Создаем тег

Отправляем тег в репозиторий

Добавлен тег:

Публикация пакета на Packagist

Переходим на сайт packagist.org, выбираем «Submit».

Указываем ссылку на репозиторий Github и выполняем проверку:

После проверки снова нажимаем «Submit» и пакет будет опубликован:

Скрипты Composer

Скрипт - это определенный сценарий, который выполняется по какому-либо событию, например, установка зависимостей или сброс автозагрузчика.

Таким сценарием может быть любой набор команд командной строки или статический метод PHP-класса.

Существует несколько видов событий:

  • Командные события
  • События установщика
  • События пакета
  • События плагина

Определение сценариев

Чтобы определить сценарий, в файле composer.json добавляется свойство scripts, которое содержит пары «событие» - «сценарий». Сценарий может быть объявлен как строка для выполнения одного действия или как массив для указания нескольких скриптов.

Пример объявления скрипта как статический метод PHP:

Пример объявления скрипта как команда командной строки:

Запуск скриптов и пользовательские команды

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

Например, команда:

запустит все сценарии, которые определены для события post-install-cmd.

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

Пример:

Запустить скрипт можно с помощью команды run-script, либо как собственную команду composer:

Плагины Composer

Плагин - это обычный пакет, который используется для расширения функциональности при необходимости.

Основное отличие заключается в том, что в composer.json пакет плагина должен иметь тип composer-plugin, атрибут extra должен содержать один или множество классов плагина, а также должен быть подключен специальный пакет composer-plugin-api.

Плагин подключается в проект как обычный пакет Composer. Он также должен быть загружен на Packagist.

Пример:

Создание плагина

Каждый плагин должен реализовывать интерфейс PluginInterface.

Интерфейс содержит методы, в которые передаются экземпляры классов Composer\Composer и Composer\IO\IOInterface.

С помощью этих двух объектов можно прочитать всю конфигурацию, а также управлять всеми внутренними объектами и состоянием.

Также, плагины могут реализовывать EventSubscriberInterface для автоматической регистрации обработчиков событий при загрузке плагина.

Пример класса плагина с обработками события:

Возможности плагина

Composer предоставляет так называемый набор возможностей, которые могут быть реализованы плагинами. Их цель состоит в том, чтобы расширить имеющиеся возможности, не прибегая к изменению внутреннего состояния экземпляра класс Composer.

Чтобы добавить использование возможностей, класс плагина должен реализовывать интерфейс Capable. Данный интерфейс содержит метод getCapabilities(), который возвращает массив с ключом в качестве имени класса Composer Capability и значением в виде собственного имени класса реализации плагина указанной возможности.

Пример реализации собственного поставщика команд.

Команда:

Поставщик команд:

После этого в проекте, где подключен плагин, можно использовать команду:

Выводы

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