Все статьи

Composer

Что такое Composer, и чем он управляет.
May 14, 2018

Эту статью можно было бы также назвать "Composer для самых маленьких".

Однако, здравствуйте.

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

Итак, Composer — менеджер пакетов для PHP.

Для чего нужен Composer и простейший пример его использования

Возьмем для примера этот проект.

Если в двух словах: то это набор скриптов для работы в VK API. Соответственно, для работы этих скриптов нужно несколько библиотек. Библиотеки перечислены в файле composer.json — ключевом файле при работе с composer.

Пример composer.json

{ "name": "dosjein/vkdeepmine", "description": "DeepMine service for Vkontakti", "license": "top-secret", "authors": [ { "name": "John Dosje", "email": "dosjein@gmail.com" } ], "minimum-stability": "dev", "require": { "vlucas/phpdotenv": "~1.", "erusev/parsedown": "^1.6", "getjump/vk": "*", "guzzlehttp/guzzle": "*" } }

В этом проекте используется пять библиотек. Если разработчик решит опубликовать этот проект на github, то ему достаточно закинуть в репозиторий папку со скриптами и составить composer.json, в котором будут описаны библиотеки, необходимые для работы этого проекта. В репозиторий не нужно вслед за файлами прицепом тащить все нужные библиотеки: занимает меньше места, проще распространять проект.

Пример работы.

Скачиваем проект:

image
composer install


image

После установки появляется папка vendor, куда складываются установленные пакеты и формируется файл

autoload.php

image
image

Этот файл подключаем к проекту и всё: библиотеки подключены, можно спокойно с ними работать.

Простота очевидна: не нужно скачивать и подключать библиотеки и их зависимости самостоятельно, composer всё сделает за вас. И вся эта пачка подключается одним единственным файлом autoload.php Все пакеты, которые лежат в vendor, добавляются в автозагрузчик. При этом composer опирается на файлы composer.json, которые должны быть у каждого пакета. Формирование composer.json пакета — это задача разработчика пакета, от потребителя пакета требуется лишь описать в composer.json проекта, какие пакеты нужно подключить.

Пример composer.json проекта

{ "name": "dosjein/vkdeepmine", "description": "DeepMine service for Vkontakti", "license": "top-secret", "authors": [ { "name": "John Dosje", "email": "dosjein@gmail.com" } ], "minimum-stability": "dev", "require": { "vlucas/phpdotenv": "~1.", "erusev/parsedown": "^1.6", "getjump/vk": "*", "guzzlehttp/guzzle": "*" } }

Пример composer.json пакета

{ "name": "getjump/vk", "description": "Library for work with API Vk.com", "keywords": ["php", "vk", "api", "library", "vkontakte"], "license": "MIT", "authors": [ { "name" : "Pavel S.", "email" : "contact@getjump.me" } ], "require": { "guzzlehttp/guzzle": "6.*", "php": ">=5.5.0" }, "require-dev": { "phpunit/phpunit": "4.1.*" }, "autoload": { "psr-4": { "getjump\\Vk\\": "src/getjump/Vk/" } } }

В секции require прописана зависимость этого пакета — библиотека guzzle http, необходимая для работы библиотеки getjump/vk. В данном случае, т.е. с точки зрения потребителя пакетов, всевозможные зависимости пакетов — это не наша забота, с зависимостями composer разберётся сам.

Пространство имён пакета прописано в секции autoload:

getjump\\Vk\\ — наименование пространства имёнsrc/getjump/Vk/ — директория, в которой лежат файлы с классами пакета.

src/getjump/Vk/ — директория, в которой лежат файлы с классами пакета.

Пример работы с этой библиотекой в проекте:

image

Core и Friends — это классы библиотеки, которые разложены и прописаны в папке src в соответствии со стандартом PSR-4. Опять же формирование структуры пакета — это работа создателя пакета.

Нам, как потребителю пакета, достаточно прописать в наш проект:

include '../vendor/autoload.php';


Установка

Установка Composer глобально

1) Для начала нужно, чтобы путь к директории с интерпретатором PHP был прописан в переменной окружения path. Проверим, так ли это:

php –version
image

Если вывод получился типа такого, то этот шаг можно пропустить.

На примере Windows 7

Система -> Дополнительные параметры системы -> Дополнительно -> Переменные среды. Далее нас будет интересовать переменная path:

image

Вписываем путь к интерпретатору:

image

* С давних времён у меня на компьютере лежит сборка xampp, сама сборка здесь не нужна, а вот интерпретатор с неё вполне подойдёт (версия PHP – 5.6).

2) Перезапускаем терминал.

Создаём директорию и ставим composer (я ставил на диск D):

D: cd / mkdir bin cd bin php -r «readfile('https://getcomposer.org/installer');» | php echo php "%~dp0composer.phar" %*>composer.bat
image

3) Добавим в переменную окружения path путь к composer.bat, например для D:\bin должно получиться:

image

Чтобы было удобнее использовать инструменты, глобально установленные через Composer, дополнительно можно добавить в path:

D:\Users\%userName%\AppData\Roaming\Composer\vendor\bin\

* У меня папка Users располагается на диске D, а на C создан симлинк на неё.

Всё, composer установлен и полностью готов к работе.

Ещё при установке можно словить ошибку:

[RuntimeException] The APPDATA or COMPOSER_HOME environment variable must be set for composer to run correctly

Решение нашлось здесь github.com/composer/composer/issues/2033

Добавляем переменную

D:\Users\GSU\AppData\Roaming

image

Установка Composer локально

Есть вариант поставить composer локально, но в большинстве случаев в этом нет явной необходимости.

Однако, тут установка ещё проще.

Так как программа глобально не установлена, нужен загрузочный файл (мини-программа composer). Для его загрузки пишем команду:

php -r «readfile('https://getcomposer.org/installer');» | php

Теперь в директории проекта появился файл composer.phar

Composer готов к использованию:

php composer.phar require [название пакета]

Отличия глобальной и локальной установок

Команды запускаются по-разному при локальной и глобальной установках:

Например:

  • локально: php composer.phar require silex/silex ~1.1
  • глобально: composer require silex/silex ~1.1

При локальной установке нужно каждый раз скачивать установочный файл в папку текущего проекта

php -r «readfile('https://getcomposer.org/installer');» | php

При глобальной установке этот файл не нужен. Composer запускается при любой текущей директории.

Команды

install — установка пакетов, прописанных в composer.json.

update – обновление пакетов.

dumpautoload — пересборка автозагрузчика.

require somepackage/somepackage:someversion — добавление нового пакета (по умолчанию пакеты ставятся из оф. репозитория). При установке пакет прописывается в composer.json.

update --lock — обновление файла блокировки composer.lock.

config --global cache-files-maxsize «2048MiB» — пример изменения параметра конфигурации.

--profile — добавление этого параметра к любой команде включит показ времени выполнения и объёма использованной памяти.

--verbose — подробная инфомация о выполняемой операции.

show --installed — список установленных пакетов с описанием каждого.

show --platform — сведения о PHP.

--dry-run — репетиция выполнения команды. Может добавляться к командам install и update. Эмулирует выполнение команды без её непосредственного выполнения. Необходима, чтобы проверить, пройдёт ли установка пакетов и зависимостей успешно.

remove — удаление пакета. Точная противоположность require.

Синтаксис composer.json

Имя пакета состоит из двух частей разделёyных косой чертой: названия поставщика (vendor name) и названия библиотеки.

"getjump/vk": "*",

Если пакет оформлен в соответствии со стандартом PSR-4, но опубликован не на packagist.org, а на github, то вместо версии пакета нужно прописать ветку и репозиторий для этого пакета:

"repositories": [ { "type": "git", "url": "http://github.com/gears-php/framework" } ], "require": { "gears-php/framework": "dev-master", "mustangostang/spyc": "dev-master" }

Пример подключения библиотеки, которая лежит на github, но при этом не оформлена по стандарту PSR-4, а представляет из себя обыкновенное нагромождение файлов с классами и функциями:

image

Pqr/superlib — эта та самая «неправильная» библиотека.

В секции repositories для неё пишем такую конструкцию:

{ "type": "package", "package": { "name": "pqr/superlib", "version": "1.2.3", "source": { "type": "git", "url": "http://github.com/pqr/superlib", "reference": "master" }, "autoload": { "classmap": [ "timer.php" ], "files": [ "lib_functions.php" ] } } }

Ключевой момент: в секции autoload указываем нужные нам файлы с классами и функциями.

Структура библиотеки

image

Содержимое файлов

image
image

Соответственно, в проекте вызов getCurrentTime() будет выглядеть примерно так:

$timer = new pqr\superlib\TimerClass; echo $timer->getCurrentTime();

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

При указании допустимых версий пакетов можно использовать точное соответствие (1.2.3), диапазоны с операторами сравнения (<1.2.3), комбинации этих операторов (>1.2.3 <1.3), “последнюю доступную” (1.2.*), символ тильды (~1.2.3) и знак вставки (^1.2.3).

Указание тильды (~1.2.3) будет включать в себя все версии до 1.3 (не включительно), так как в семантическом версионировании это является моментом внедрения новых функциональных возможностей. В данном случае будет получена последняя из стабильных минорных версий, то есть будет меняться только последняя цифра — 1.2.5, 1.2.8 и т.д.

Указание знака вставки (^1.2.3) буквально означает “опасаться только критических изменений” и будет включать в себя версии вплоть до 2.0. Применительно к семантическому версионированию, изменение мажорной версии является моментом внесения в проект критических изменений, так что версии 1.3, 1.4 и 1.9 подходят, в то время как 2.0 — уже нет, то есть не меняется только первая цифра.

Тильда: ~1.2.3 — это самый распространённый и безопасный способ указания версии.

Файл composer.lock

Файл composer.lock сохраняет текущий список установленных зависимостей и их версии. Таким образом, когда версии зависимостей уже будут обновлены (команда update), другие люди, которые будут клонировать ваш проект, получат те же самые версии. Это позволяет убедиться в том, что каждый, кто получает ваш проект, имеет пакетное окружение, идентичное тому, которое вы использовали при разработке, и помогает избежать ошибок, которые могли бы возникнуть из-за обновления версий.

При каждом выполнении команды update версии обновлённый пакетов прописываются в composer.lock. Этот файл загоняется под систему контроля версий и при установке пакетов на новом сервере поставятся именно те версии пакетов, которые прописаны в этом файле. При выполнении команды install composer будет в первую очередь опираться на composer.lock. Таким образом, на разных серверах будет гарантированно установлено одинаковое пакетное окружение с точки зрения версий.

Также файл composer.lock содержит хэш файла composer.json. И если json-файл был отредактирован, то composer выдаст предупреждение, что файл lock не соответствует json-файлу.

В таком случае нужно выполнить команду composer update --lock, которая обновит composer.lock:

composer update

image

composer show --installed

image

composer install

image
image

Отличие install от update в контексте использования composer.lock

Команда composer install проверяет, существует ли composer.lock:

  • если нет, резолвит зависимости и создаёт его;
  • если composer.lock: существует, устанавливает версии, указанные в нём.

Команда composer update:

  • проверяет composer.json;
  • определяет последние версии на основе указанных в этом файле;
  • устанавливает последние версии;
  • обновляет composer.lock в соответствии с установленными.

Пример использования с точки зрения создателя проекта

Имеем проект без установленных пакетов:

image

Поставим несколько библиотек:

composer require "getjump/vk:*"
image
image

У нас сформировался composer.json с информацией о пакетах:

image

Мы можем его дополнить и распространять проект с этим файлом:

{ "name": "gsu/gsu", "description": "Test project", "license": "top-secret", "authors": [ { "name": "Sergey", "email": "gsu1234@mail.ru" } ], "require": { "getjump/vk": "*", "mustangostang/spyc": "^0.6.2" } }

Другой пользователь скачал наш проект, выполнил install, и у него в проекте развернулись все нужные пакеты:

image

Пример использования с точки зрения создателя пакета


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

image

Класс оформлен как пакет и залит на github.

image

Составлен composer.json:

{ "name": "gsu/helperurl", "description": "Helper URL", "keywords": ["url"], "license": "MIT", "authors": [ { "name": "Sergey G.", "email": "gsu1234@mail.ru" } ], "require": { "php": ">=5.5.0" }, "autoload": { "psr-4": { "gsu\\helperurl\\": "src/gsu/helperurl/" } } }


Регистрируюсь на официальном репозитории и добавляю пакет, указывая ссылку на репозиторий, в котором он лежит:

image

Всё, пакет добавлен:

image
image

Проверяю работоспособность пакета:

composer require gsu/helperurl
image