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-projektu

Як nazev-projektu введіть назву каталогу для свого проекту та підтвердіть. 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