Composer: wskazówki użycia

Composer to narzędzie do zarządzania zależnościami w PHP. Pozwala zadeklarować biblioteki, od których zależy Twój projekt, a następnie sam je instaluje i aktualizuje. Dowiemy się:

  • jak zainstalować Composer
  • jak używać go w nowym albo istniejącym projekcie

Instalacja

Composer to wykonywalny plik .phar, który pobierasz i instalujesz w następujący sposób.

Windows

Użyj oficjalnego instalatora Composer-Setup.exe.

Linux, macOS

Wystarczą 4 polecenia, które możesz skopiować z tej strony.

Dodatkowo, kopiując go do katalogu znajdującego się w systemowym PATH, sprawisz, że Composer będzie dostępny globalnie:

$ mv ./composer.phar ~/bin/composer # albo /usr/local/bin/composer

Użycie w projekcie

Żeby zacząć używać Composera w swoim projekcie, wystarczy plik composer.json. Opisuje on zależności Twojego projektu i może zawierać także inne metadane. Najprostszy composer.json może wyglądać tak:

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

Mówimy tu, że nasza aplikacja (albo biblioteka) wymaga pakietu nette/database (nazwa pakietu składa się z nazwy dostawcy i nazwy projektu) i że chce wersję odpowiadającą warunkowi ^3.0 (czyli najnowszą wersję 3).

Mając więc plik composer.json w katalogu głównym projektu, uruchom:

composer update

Composer pobierze Nette Database do katalogu vendor/. Utworzy też plik composer.lock, który zawiera informacje o tym, jakie dokładnie wersje bibliotek zainstalował.

Composer wygeneruje plik vendor/autoload.php. Wystarczy go dołączyć i możesz zacząć używać klas z bibliotek bez żadnej dodatkowej pracy:

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

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

Aktualizacja pakietów do najnowszych wersji

Do aktualizacji używanych bibliotek do najnowszych wersji zgodnych z warunkami zdefiniowanymi w composer.json służy polecenie composer update. Na przykład przy zależności "nette/database": "^3.0" zainstaluje najnowszą wersję 3.x.x, ale nie wersję 4.

Żeby zaktualizować warunki w pliku composer.json, na przykład na "nette/database": "^4.1", i pozwolić na instalację najnowszej wersji, użyj polecenia composer require nette/database.

Żeby zaktualizować wszystkie używane pakiety Nette, musiałbyś wypisać je wszystkie w wierszu poleceń, np.:

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

To niepraktyczne. Użyj więc prostego skryptu Composer Frontline, który zrobi to za Ciebie:

php composer-frontline.php

Tworzenie nowego projektu

Nowy projekt Nette utworzysz jednym poleceniem:

composer create-project nette/web-project nazwa-projektu

Zamiast nazwa-projektu wpisz nazwę katalogu dla swojego projektu i wykonaj polecenie. Composer pobierze z GitHuba repozytorium nette/web-project, które zawiera już plik composer.json, a następnie zainstaluje sam Nette Framework. Pozostaje już tylko ustawić uprawnienia do zapisu dla katalogów temp/ i log/ i projekt powinien ożyć.

Jeśli wiesz, na jakiej wersji PHP projekt będzie hostowany, koniecznie ją ustaw.

Wersja PHP

Composer zawsze instaluje wersje pakietów zgodne z wersją PHP, której aktualnie używasz (konkretnie z wersją PHP używaną w wierszu poleceń przy uruchamianiu Composera). To nie musi być ta sama wersja, której używa Twój hosting. Dlatego bardzo ważne jest, żeby dodać do pliku composer.json informację o wersji PHP na hostingu. Wtedy zainstalują się tylko wersje pakietów zgodne z hostingiem.

Na przykład żeby ustawić, że projekt będzie działać na PHP 8.2.3, użyj polecenia:

composer config platform.php 8.2.3

Wersja zostanie zapisana w pliku composer.json w ten sposób:

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

Numer wersji PHP podaje się jednak w pliku jeszcze w innym miejscu, w sekcji require. Podczas gdy pierwszy numer określa wersję, dla której instalowane są pakiety, drugi mówi o wersji, dla której napisana jest sama aplikacja. Na jej podstawie na przykład PhpStorm ustawia PHP language level. (Oczywiście nie ma sensu, żeby te wersje się różniły, więc podwójny zapis jest przeoczeniem.) Tę wersję ustawisz poleceniem:

composer require php 8.2.3 --no-update

Albo bezpośrednio w pliku composer.json:

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

Ignorowanie wersji PHP

Pakiety zwykle podają zarówno najniższą wersję PHP, z którą są zgodne, jak i najwyższą wersję, z którą były testowane. Jeśli zamierzasz użyć jeszcze nowszej wersji PHP, na przykład w celach testowych, Composer odmówi instalacji takiego pakietu. Rozwiązaniem jest opcja --ignore-platform-req=php+, która sprawia, że Composer ignoruje górne limity wymaganej wersji PHP.

Fałszywe komunikaty

Przy aktualizacji pakietów albo zmianie numerów wersji czasem dochodzi do konfliktów. Jeden pakiet ma wymagania kolidujące z innym i tak dalej. Composer jednak czasem wypisuje fałszywe komunikaty. Zgłasza konflikt, który w rzeczywistości nie istnieje. W takiej sytuacji pomaga usunięcie pliku composer.lock i ponowna próba.

Jeśli komunikat o błędzie nie znika, jest prawdziwy i trzeba go przeczytać, żeby zrozumieć, co i jak zmodyfikować.

Packagist.org – globalne repozytorium

Packagist to główne repozytorium, w którym Composer domyślnie szuka pakietów. Możesz tu również publikować własne pakiety.

A co, jeśli nie chcemy centralnego repozytorium

Jeśli mamy w firmie wewnętrzne aplikacje albo biblioteki, których nie da się hostować publicznie, możemy utworzyć dla nich własne repozytoria.

Więcej o repozytoriach przeczytasz w oficjalnej dokumentacji.

Autoloading

Kluczową cechą Composera jest to, że zapewnia autoloading wszystkich klas, które instaluje. Aktywujesz go, dołączając plik vendor/autoload.php.

Composera możesz jednak użyć także do wczytywania innych klas spoza katalogu vendor/. Pierwsza możliwość to pozwolić Composerowi przeskanować zdefiniowane katalogi i podkatalogi, znaleźć wszystkie klasy i włączyć je do autoloadera. Osiągniesz to, ustawiając w composer.json autoload > classmap:

{
	"autoload": {
		"classmap": [
			"src/",      # włącza katalog src/ i jego podkatalogi
		]
	}
}

Następnie po każdej zmianie musisz uruchomić polecenie composer dumpautoload, żeby wygenerować tablice autoloadingu na nowo. To ogromnie niewygodne. Znacznie lepiej powierzyć to zadanie RobotLoaderowi, który tę samą czynność wykonuje automatycznie w tle i o wiele szybciej.

Druga możliwość to trzymać się PSR-4. Upraszczając, to system, w którym przestrzenie nazw i nazwy klas odpowiadają strukturze katalogów i nazwom plików, np. App\Core\RouterFactory będzie znajdować się w pliku /ścieżka/do/App/Core/RouterFactory.php. Przykład konfiguracji:

{
	"autoload": {
		"psr-4": {
			"App\\": "app/"   # przestrzeń nazw App\ jest w katalogu app/
		}
	}
}

Szczegóły konfiguracji tego zachowania znajdziesz w dokumentacji Composera.

Testowanie nowych wersji

Chcesz przetestować nową wersję rozwojową pakietu? Oto jak. Najpierw dodaj do pliku composer.json tę parę opcji. Pozwoli to instalować wersje rozwojowe, ale Composer sięgnie po nie tylko wtedy, gdy żadna kombinacja wersji stabilnych nie spełni wymagań:

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

Zalecamy też usunięcie pliku composer.lock, bo Composer czasem w niewyjaśniony sposób odmawia instalacji, a to potrafi problem rozwiązać.

Powiedzmy, że chodzi o pakiet nette/utils, a nowa wersja to 4.0. Zainstalujesz ją poleceniem:

composer require nette/utils:4.0.x-dev

Albo możesz zainstalować konkretną wersję, na przykład 4.0.0-RC2:

composer require nette/utils:4.0.0-RC2

Jeśli jednak od biblioteki zależy inny pakiet zablokowany na starszej wersji (np. ^3.1), idealnym rozwiązaniem jest zaktualizowanie tego zależnego pakietu tak, żeby działał z nową wersją. Ale jeśli chcesz tylko obejść ograniczenie i zmusić Composera do zainstalowania wersji rozwojowej, udając, że to wersja starsza (np. 3.1.6), możesz użyć słowa kluczowego as:

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

Wywoływanie poleceń

Za pośrednictwem Composera możesz wywoływać własne, wcześniej zdefiniowane polecenia i skrypty, tak jakby były natywnymi poleceniami Composera. Dla skryptów znajdujących się w katalogu vendor/bin nie musisz podawać tej ścieżki.

Jako przykład zdefiniujmy w composer.json skrypt, który za pomocą Nette Testera uruchamia testy:

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

Testy uruchomimy potem poleceniem composer tester. Polecenie możesz wywołać, nawet jeśli nie jesteś w katalogu głównym projektu, tylko w którymś z jego podkatalogów.

Wyślij podziękowanie

Pokażemy Ci trik, którym sprawisz radość autorom open source. Możesz w prosty sposób dać gwiazdki na GitHubie bibliotekom, których używa Twój projekt. Wystarczy zainstalować bibliotekę symfony/thanks:

composer global require symfony/thanks

A następnie uruchomić:

composer thanks

Wypróbuj!

Konfiguracja

Composer jest ściśle zintegrowany z systemem kontroli wersji Git. Jeśli nie masz zainstalowanego Gita, musisz powiedzieć Composerowi, żeby go nie używał:

composer -g config preferred-install dist