Nette Documentation Preview

syntax
Composer: wskazówki dotyczące użytkowania
*****************************************

<div class=perex>

Composer to narzędzie do zarządzania zależnościami w PHP. Umożliwia nam zdefiniowanie bibliotek, od których zależy nasz projekt, i będzie je za nas instalować oraz aktualizować. Pokażemy:

- jak zainstalować Composer
- jego użycie w nowym lub istniejącym projekcie

</div>


Instalacja
==========

Composer to plik wykonywalny `.phar`, który pobierzesz i zainstalujesz w następujący sposób:


Windows
-------

Użyj oficjalnego instalatora [Composer-Setup.exe |https://getcomposer.org/Composer-Setup.exe].


Linux, macOS
------------

Wystarczą 4 polecenia, które skopiujesz z [tej strony |https://getcomposer.org/download/].

Następnie, umieszczając go w folderze, który znajduje się w systemowym `PATH`, Composer stanie się dostępny globalnie:

```shell
$ mv ./composer.phar ~/bin/composer # lub /usr/local/bin/composer
```


Użycie w projekcie
==================

Aby móc w swoim projekcie zacząć używać Composera, potrzebujesz tylko pliku `composer.json`. Opisuje on zależności naszego projektu i może również zawierać inne metadane. Podstawowy `composer.json` może więc wyglądać tak:

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

Mówimy tutaj, że nasza aplikacja (lub biblioteka) wymaga pakietu `nette/database` (nazwa pakietu składa się z nazwy organizacji i nazwy projektu) i chce wersji, która odpowiada warunkowi `^3.0` (tj. najnowszej wersji 3).

Mamy więc w katalogu głównym projektu plik `composer.json` i uruchamiamy instalację:

```shell
composer update
```

Composer pobierze Nette Database do folderu `vendor/`. Następnie utworzy plik `composer.lock`, który zawiera informacje o tym, które wersje bibliotek dokładnie zainstalował.

Composer wygeneruje plik `vendor/autoload.php`, który możemy po prostu dołączyć i zacząć używać bibliotek bez żadnej dodatkowej pracy:

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

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


Aktualizacja pakietów do najnowszych wersji
===========================================

Za aktualizację używanych bibliotek do najnowszych wersji zgodnie z warunkami zdefiniowanymi w `composer.json` odpowiada polecenie `composer update`. Np. przy zależności `"nette/database": "^3.0"` zainstaluje najnowszą wersję 3.x.x, ale już nie wersję 4.

Aby zaktualizować warunki w pliku `composer.json`, na przykład na `"nette/database": "^4.1"`, aby można było zainstalować najnowszą wersję, użyj polecenia `composer require nette/database`.

Aby zaktualizować wszystkie używane pakiety Nette, trzeba by je wszystkie wymienić w wierszu poleceń, np.:

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

Co jest niepraktyczne. Użyj dlatego prostego skryptu "Composer Frontline":https://gist.github.com/dg/734bebf55cf28ad6a5de1156d3099bff, który to zrobi za Ciebie:

```shell
php composer-frontline.php
```


Tworzenie nowego projektu
=========================

Nowy projekt Nette utworzysz za pomocą jednego polecenia:

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

Jako `nazwa-projektu` wstaw nazwę katalogu dla swojego projektu i potwierdź. Composer pobierze repozytorium `nette/web-project` z GitHubu, które już zawiera plik `composer.json`, a zaraz potem Nette Framework. Powinno już wystarczyć tylko [ustawić uprawnienia |nette:troubleshooting#Ustawianie uprawnień do katalogów] do zapisu w folderach `temp/` i `log/`, a projekt powinien ożyć.

Jeśli wiesz, na jakiej wersji PHP projekt będzie hostowany, nie zapomnij [jej ustawić |#Wersja PHP].


Wersja PHP
==========

Composer zawsze instaluje te wersje pakietów, które są kompatybilne z wersją PHP, której właśnie używasz (a raczej z wersją PHP używaną w wierszu poleceń podczas uruchamiania Composera). Co jednak najprawdopodobniej nie jest tą samą wersją, której używa Twój hosting. Dlatego bardzo ważne jest dodanie do pliku `composer.json` informacji o wersji PHP na hostingu. Wtedy będą instalowane tylko wersje pakietów kompatybilne z hostingiem.

To, że projekt będzie działał na przykład na PHP 8.2.3, ustawimy poleceniem:

```shell
composer config platform.php 8.2.3
```

W ten sposób wersja zostanie zapisana do pliku `composer.json`:

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

Jednak numer wersji PHP podaje się jeszcze w innym miejscu pliku, a mianowicie w sekcji `require`. Podczas gdy pierwszy numer określa, dla jakiej wersji będą instalowane pakiety, drugi numer mówi, dla jakiej wersji jest napisana sama aplikacja. A według niego na przykład PhpStorm ustawia *PHP language level*. (Oczywiście nie ma sensu, aby te wersje się różniły, więc podwójny zapis jest niedopatrzeniem.) Tę wersję ustawisz poleceniem:

```shell
composer require php 8.2.3 --no-update
```

Lub bezpośrednio w pliku `composer.json`:

```js
{
	"require": {
		"php": "8.2.3"
	}
}
```


Ignorowanie wersji PHP
======================

Pakiety zazwyczaj mają podaną zarówno najniższą wersję PHP, z którą są kompatybilne, jak i najwyższą, z którą są testowane. Jeśli zamierzasz używać wersji PHP jeszcze nowszej, na przykład w celu testowania, Composer odmówi zainstalowania takiego pakietu. Rozwiązaniem jest opcja `--ignore-platform-req=php+`, która spowoduje, że Composer będzie ignorować górne limity wymaganej wersji PHP.


Fałszywe komunikaty
===================

Podczas aktualizacji pakietów lub zmian numerów wersji zdarza się, że dochodzi do konfliktu. Jeden pakiet ma wymagania, które są sprzeczne z innym i podobnie. Composer jednak czasami wypisuje fałszywe komunikaty. Zgłasza konflikt, który realnie nie istnieje. W takim przypadku pomaga usunięcie pliku `composer.lock` i spróbowanie ponownie.

Jeśli komunikat błędu nadal się pojawia, to jest on myśleny poważnie i trzeba z niego wyczytać, co i jak zmodyfikować.


Packagist.org - centralne repozytorium
======================================

[Packagist |https://packagist.org] to główne repozytorium, w którym Composer stara się wyszukiwać pakiety, jeśli mu nie powiemy inaczej. Możemy tutaj publikować również własne pakiety.


Co jeśli nie chcemy używać centralnego repozytorium?
----------------------------------------------------

Jeśli mamy wewnętrzne aplikacje firmowe, których po prostu nie możemy hostować publicznie, to stworzymy dla nich firmowe repozytorium.

Więcej na temat repozytoriów [w oficjalnej dokumentacji |https://getcomposer.org/doc/05-repositories.md#repositories].


Autoloading
===========

Zasadniczą cechą Composera jest to, że zapewnia autoloading dla wszystkich przez niego zainstalowanych klas, który uruchamiasz przez dołączenie pliku `vendor/autoload.php`.

Jednak możliwe jest używanie Composera również do ładowania innych klas spoza folderu `vendor`. Pierwszą możliwością jest pozwolenie Composerowi przeszukać zdefiniowane foldery i podfoldery, znaleźć wszystkie klasy i dołączyć je do autoloadera. Osiągniesz to ustawiając `autoload > classmap` w `composer.json`:

```js
{
	"autoload": {
		"classmap": [
			"src/",      #  dołączy folder src/ i jego podfoldery
		]
	}
}
```

Następnie przy każdej zmianie trzeba uruchomić polecenie `composer dumpautoload` i pozwolić na przegenerowanie tabel autoloadingu. To jest niezwykle niewygodne i znacznie lepiej jest powierzyć to zadanie [RobotLoaderowi|robot-loader:], który tę samą czynność wykonuje automatycznie w tle i znacznie szybciej.

Drugą możliwością jest przestrzeganie [PSR-4|https://www.php-fig.org/psr/psr-4/]. Uproszczając, chodzi o system, w którym przestrzenie nazw i nazwy klas odpowiadają strukturze katalogów i nazwom plików, czyli np. `App\Core\RouterFactory` będzie w pliku `/path/to/App/Core/RouterFactory.php`. Przykład konfiguracji:

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

Jak dokładnie skonfigurować zachowanie dowiesz się w [dokumentacji Composera|https://getcomposer.org/doc/04-schema.md#psr-4].


Testowanie nowych wersji
========================

Chcesz przetestować nową wersję rozwojową pakietu. Jak to zrobić? Najpierw do pliku `composer.json` dodaj tę parę opcji, która pozwoli instalować wersje rozwojowe pakietów, jednak ucieknie się do tego tylko w przypadku, gdy nie istnieje żadna kombinacja stabilnych wersji, która spełniałaby wymagania:

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

Następnie zalecamy usunięcie pliku `composer.lock`, czasami bowiem Composer niezrozumiale odmawia instalacji i to rozwiązuje problem.

Powiedzmy, że chodzi o pakiet `nette/utils` i nowa wersja ma numer 4.0. Zainstalujesz ją poleceniem:

```shell
composer require nette/utils:4.0.x-dev
```

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

```shell
composer require nette/utils:4.0.0-RC2
```

Gdy jednak od biblioteki zależy inny pakiet, który jest zablokowany na starszej wersji (np. `^3.1`), to idealnie jest zaktualizować pakiet, aby działał z nową wersją. Jeśli jednak chcesz tylko obejść ograniczenie i zmusić Composera do zainstalowania wersji rozwojowej i udawania, że jest to wersja starsza (np. 3.1.6), możesz użyć słowa kluczowego `as`:

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


Wywoływanie poleceń
===================

Przez Composer można wywoływać własne przygotowane polecenia i skrypty, jakby były to natywne polecenia Composera. W przypadku skryptów, które znajdują się w folderze `vendor/bin`, nie trzeba podawać tego folderu.

Jako przykład zdefiniujemy w pliku `composer.json` skrypt, który za pomocą [Nette Testera|tester:] uruchomi testy:

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

Testy następnie uruchomimy za pomocą `composer tester`. Polecenie możemy wywołać również w przypadku, gdy nie jesteśmy w folderze głównym projektu, ale w którymś podkatalogu.


Wyślij podziękowania
====================

Pokażemy Ci sztuczkę, którą ucieszysz autorów open source. W prosty sposób dasz na GitHubie gwiazdkę bibliotekom, których używa Twój projekt. Wystarczy zainstalować bibliotekę `symfony/thanks`:

```shell
composer global require symfony/thanks
```

A następnie uruchomić:

```shell
composer thanks
```

Spróbuj!


Konfiguracja
============

Composer jest ściśle powiązany z narzędziem do wersjonowania [Git |https://git-scm.com]. Jeśli go nie masz zainstalowanego, trzeba powiedzieć Composerowi, aby go nie używał:

```shell
composer -g config preferred-install dist
```

{{sitename: Best Practices}}

Composer: wskazówki dotyczące użytkowania

Composer to narzędzie do zarządzania zależnościami w PHP. Umożliwia nam zdefiniowanie bibliotek, od których zależy nasz projekt, i będzie je za nas instalować oraz aktualizować. Pokażemy:

  • jak zainstalować Composer
  • jego użycie w nowym lub istniejącym projekcie

Instalacja

Composer to plik wykonywalny .phar, który pobierzesz i zainstalujesz w następujący sposób:

Windows

Użyj oficjalnego instalatora Composer-Setup.exe.

Linux, macOS

Wystarczą 4 polecenia, które skopiujesz z tej strony.

Następnie, umieszczając go w folderze, który znajduje się w systemowym PATH, Composer stanie się dostępny globalnie:

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

Użycie w projekcie

Aby móc w swoim projekcie zacząć używać Composera, potrzebujesz tylko pliku composer.json. Opisuje on zależności naszego projektu i może również zawierać inne metadane. Podstawowy composer.json może więc wyglądać tak:

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

Mówimy tutaj, że nasza aplikacja (lub biblioteka) wymaga pakietu nette/database (nazwa pakietu składa się z nazwy organizacji i nazwy projektu) i chce wersji, która odpowiada warunkowi ^3.0 (tj. najnowszej wersji 3).

Mamy więc w katalogu głównym projektu plik composer.json i uruchamiamy instalację:

composer update

Composer pobierze Nette Database do folderu vendor/. Następnie utworzy plik composer.lock, który zawiera informacje o tym, które wersje bibliotek dokładnie zainstalował.

Composer wygeneruje plik vendor/autoload.php, który możemy po prostu dołączyć i zacząć używać bibliotek bez żadnej dodatkowej pracy:

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

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

Aktualizacja pakietów do najnowszych wersji

Za aktualizację używanych bibliotek do najnowszych wersji zgodnie z warunkami zdefiniowanymi w composer.json odpowiada polecenie composer update. Np. przy zależności "nette/database": "^3.0" zainstaluje najnowszą wersję 3.x.x, ale już nie wersję 4.

Aby zaktualizować warunki w pliku composer.json, na przykład na "nette/database": "^4.1", aby można było zainstalować najnowszą wersję, użyj polecenia composer require nette/database.

Aby zaktualizować wszystkie używane pakiety Nette, trzeba by je wszystkie wymienić w wierszu poleceń, np.:

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

Co jest niepraktyczne. Użyj dlatego prostego skryptu Composer Frontline, który to zrobi za Ciebie:

php composer-frontline.php

Tworzenie nowego projektu

Nowy projekt Nette utworzysz za pomocą jednego polecenia:

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

Jako nazwa-projektu wstaw nazwę katalogu dla swojego projektu i potwierdź. Composer pobierze repozytorium nette/web-project z GitHubu, które już zawiera plik composer.json, a zaraz potem Nette Framework. Powinno już wystarczyć tylko ustawić uprawnienia do zapisu w folderach temp/ i log/, a projekt powinien ożyć.

Jeśli wiesz, na jakiej wersji PHP projekt będzie hostowany, nie zapomnij jej ustawić.

Wersja PHP

Composer zawsze instaluje te wersje pakietów, które są kompatybilne z wersją PHP, której właśnie używasz (a raczej z wersją PHP używaną w wierszu poleceń podczas uruchamiania Composera). Co jednak najprawdopodobniej nie jest tą samą wersją, której używa Twój hosting. Dlatego bardzo ważne jest dodanie do pliku composer.json informacji o wersji PHP na hostingu. Wtedy będą instalowane tylko wersje pakietów kompatybilne z hostingiem.

To, że projekt będzie działał na przykład na PHP 8.2.3, ustawimy poleceniem:

composer config platform.php 8.2.3

W ten sposób wersja zostanie zapisana do pliku composer.json:

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

Jednak numer wersji PHP podaje się jeszcze w innym miejscu pliku, a mianowicie w sekcji require. Podczas gdy pierwszy numer określa, dla jakiej wersji będą instalowane pakiety, drugi numer mówi, dla jakiej wersji jest napisana sama aplikacja. A według niego na przykład PhpStorm ustawia PHP language level. (Oczywiście nie ma sensu, aby te wersje się różniły, więc podwójny zapis jest niedopatrzeniem.) Tę wersję ustawisz poleceniem:

composer require php 8.2.3 --no-update

Lub bezpośrednio w pliku composer.json:

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

Ignorowanie wersji PHP

Pakiety zazwyczaj mają podaną zarówno najniższą wersję PHP, z którą są kompatybilne, jak i najwyższą, z którą są testowane. Jeśli zamierzasz używać wersji PHP jeszcze nowszej, na przykład w celu testowania, Composer odmówi zainstalowania takiego pakietu. Rozwiązaniem jest opcja --ignore-platform-req=php+, która spowoduje, że Composer będzie ignorować górne limity wymaganej wersji PHP.

Fałszywe komunikaty

Podczas aktualizacji pakietów lub zmian numerów wersji zdarza się, że dochodzi do konfliktu. Jeden pakiet ma wymagania, które są sprzeczne z innym i podobnie. Composer jednak czasami wypisuje fałszywe komunikaty. Zgłasza konflikt, który realnie nie istnieje. W takim przypadku pomaga usunięcie pliku composer.lock i spróbowanie ponownie.

Jeśli komunikat błędu nadal się pojawia, to jest on myśleny poważnie i trzeba z niego wyczytać, co i jak zmodyfikować.

Packagist.org – centralne repozytorium

Packagist to główne repozytorium, w którym Composer stara się wyszukiwać pakiety, jeśli mu nie powiemy inaczej. Możemy tutaj publikować również własne pakiety.

Co jeśli nie chcemy używać centralnego repozytorium?

Jeśli mamy wewnętrzne aplikacje firmowe, których po prostu nie możemy hostować publicznie, to stworzymy dla nich firmowe repozytorium.

Więcej na temat repozytoriów w oficjalnej dokumentacji.

Autoloading

Zasadniczą cechą Composera jest to, że zapewnia autoloading dla wszystkich przez niego zainstalowanych klas, który uruchamiasz przez dołączenie pliku vendor/autoload.php.

Jednak możliwe jest używanie Composera również do ładowania innych klas spoza folderu vendor. Pierwszą możliwością jest pozwolenie Composerowi przeszukać zdefiniowane foldery i podfoldery, znaleźć wszystkie klasy i dołączyć je do autoloadera. Osiągniesz to ustawiając autoload > classmap w composer.json:

{
	"autoload": {
		"classmap": [
			"src/",      #  dołączy folder src/ i jego podfoldery
		]
	}
}

Następnie przy każdej zmianie trzeba uruchomić polecenie composer dumpautoload i pozwolić na przegenerowanie tabel autoloadingu. To jest niezwykle niewygodne i znacznie lepiej jest powierzyć to zadanie RobotLoaderowi, który tę samą czynność wykonuje automatycznie w tle i znacznie szybciej.

Drugą możliwością jest przestrzeganie PSR-4. Uproszczając, chodzi o system, w którym przestrzenie nazw i nazwy klas odpowiadają strukturze katalogów i nazwom plików, czyli np. App\Core\RouterFactory będzie w pliku /path/to/App/Core/RouterFactory.php. Przykład konfiguracji:

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

Jak dokładnie skonfigurować zachowanie dowiesz się w dokumentacji Composera.

Testowanie nowych wersji

Chcesz przetestować nową wersję rozwojową pakietu. Jak to zrobić? Najpierw do pliku composer.json dodaj tę parę opcji, która pozwoli instalować wersje rozwojowe pakietów, jednak ucieknie się do tego tylko w przypadku, gdy nie istnieje żadna kombinacja stabilnych wersji, która spełniałaby wymagania:

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

Następnie zalecamy usunięcie pliku composer.lock, czasami bowiem Composer niezrozumiale odmawia instalacji i to rozwiązuje problem.

Powiedzmy, że chodzi o pakiet nette/utils i nowa wersja ma numer 4.0. Zainstalujesz ją poleceniem:

composer require nette/utils:4.0.x-dev

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

composer require nette/utils:4.0.0-RC2

Gdy jednak od biblioteki zależy inny pakiet, który jest zablokowany na starszej wersji (np. ^3.1), to idealnie jest zaktualizować pakiet, aby działał z nową wersją. Jeśli jednak chcesz tylko obejść ograniczenie i zmusić Composera do zainstalowania wersji rozwojowej i udawania, że jest 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ń

Przez Composer można wywoływać własne przygotowane polecenia i skrypty, jakby były to natywne polecenia Composera. W przypadku skryptów, które znajdują się w folderze vendor/bin, nie trzeba podawać tego folderu.

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

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

Testy następnie uruchomimy za pomocą composer tester. Polecenie możemy wywołać również w przypadku, gdy nie jesteśmy w folderze głównym projektu, ale w którymś podkatalogu.

Wyślij podziękowania

Pokażemy Ci sztuczkę, którą ucieszysz autorów open source. W prosty sposób dasz na GitHubie gwiazdkę bibliotekom, których używa Twój projekt. Wystarczy zainstalować bibliotekę symfony/thanks:

composer global require symfony/thanks

A następnie uruchomić:

composer thanks

Spróbuj!

Konfiguracja

Composer jest ściśle powiązany z narzędziem do wersjonowania Git. Jeśli go nie masz zainstalowanego, trzeba powiedzieć Composerowi, aby go nie używał:

composer -g config preferred-install dist