Nette Documentation Preview

syntax
Composer: tipy pro použití
**************************

<div class=perex>

Composer je nástroj pro správu závislostí v PHP. Umožní nám vyjmenovat knihovny, na kterých náš projekt závisí, a bude je za nás instalovat a aktualizovat. Ukážeme si:

- jak Composer nainstalovat
- jeho použití v novém či stávajícím projektu

</div>


Instalace
=========

Composer je spustitelný `.phar` soubor, který si stáhnete a nainstalujete následujícím způsobem:


Windows
-------

Použijte oficiální instalátor [Composer-Setup.exe |https://getcomposer.org/Composer-Setup.exe].


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

Stačí 4 příkazy, které si zkopírujte z [této stránky |https://getcomposer.org/download/].

Dále vložením do složky, která je v systémovém `PATH`, se stane Composer přístupný globálně:

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


Použití v projektu
==================

Abychom mohli ve svém projektu začít používat Composer, potřebujete pouze soubor `composer.json`. Ten popisuje závislosti našeho projektu a může také obsahovat další metadata. Základní `composer.json` tedy může vypadat takto:

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

Říkáme zde, že naše aplikace (nebo knihovna) vyžaduje balíček `nette/database` (název balíčku se skládá z názvu organizace a názvu projektu) a chce verzi, která odpovídá podmínce `^3.0` (tj. nejnovější verzi 3).

Máme tedy v kořenu projektu soubor `composer.json` a spustíme instalaci:

```shell
composer update
```

Composer stáhne Nette Database do složky `vendor/`. Dále vytvoří soubor `composer.lock`, který obsahuje informace o tom, které verze knihoven přesně nainstaloval.

Composer vygeneruje soubor `vendor/autoload.php`, který můžeme jednoduše inkludovat a začít používat knihovny bez jakékoli další práce:

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

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


Aktualizace balíčků na nejnovější verze
=======================================

Aktualizaci použiváných knihoven na nejnovější verze podle podmínek definovaných v `composer.json` má na starosti příkaz `composer update`. Např. u závislosti `"nette/database": "^3.0"` nainstaluje nejnovější verzi 3.x.x, ale nikoliv už verzi 4.

Pro aktualizaci podmínek v souboru `composer.json` například na `"nette/database": "^4.1"`, aby bylo možné nainstalovat nejnovější verzi, použijte příkaz `composer require nette/database`.

Pro aktualizaci všech používaných balíčků Nette by bylo nutné je všechny v příkazové řádce vyjmenovat, např.:

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

Což je nepraktické. Použijte proto jednoduchý skript "Composer Frontline":https://gist.github.com/dg/734bebf55cf28ad6a5de1156d3099bff, který to udělá za vás:

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


Vytvoření nového projektu
=========================

Nový projekt na Nette vytvoříte pomocí jediného příkazu:

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

Jako `nazev-projektu` vložte název adresáře pro svůj projekt a potvrďte. Composer stáhne repozitář `nette/web-project` z GitHubu, který už obsahuje soubor `composer.json`, a hned potom Nette Framework. Mělo by již stačit pouze [nastavit oprávnění |nette:troubleshooting#nastaveni-prav-adresaru] na zápis do složek `temp/` a `log/` a projekt by měl ožít.

Pokud víte, na jaké verzi bude PHP projekt hostován, nezapomeňte [ji nastavit |#Verze PHP].


Verze PHP
=========

Composer vždy instaluje ty verze balíčků, které jsou kompatibilní s verzí PHP, kterou právě používáte (lépe řečeno s verzí PHP používanou v příkazové řádce při spouštění Composeru). Což ale nejspíš není stejná verze, jakou používá váš hosting. Proto je velmi důležité si do souboru `composer.json` přidat informaci o verzi PHP na hostingu. Poté se budou instalovat pouze verze balíčků s hostingem kompatibilní.

To, že projekt poběží například na PHP 8.2.3, nastavíme příkazem:

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

Takto se verze zapíše do souboru `composer.json`:

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

Nicméně číslo verze PHP se uvádí ještě na jiném místě souboru, a to v sekci `require`. Zatímco první číslo určuje, pro jakou verzi se budou instalovat balíčky, druhé číslo říká, pro jakou verzi je napsaná samotná aplikace.
A podle něj například PhpStorm nastavuje *PHP language level*. (Samozřejmě nedává smysl, aby se tyto verze lišily, takže dvojí zápis je nedomyšlenost.) Tuto verzi nastavíte příkazem:

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

Nebo přímo v souboru `composer.json`:

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


Ignorování verze PHP
====================

Balíčky zpravidla mívají uvedenou jak nejnižší verzi PHP, se kterou jsou kompatibilní, tak i nejvyšší, se kterou jsou testované. Pokud se chystáte používat verzi PHP ještě novější, třeba z důvodu testování, Composer odmítne takový balíček nainstalovat. Řešením je volba `--ignore-platform-req=php+`, která způsobí, že Composer bude ignorovat horní limity požadované verze PHP.


Planá hlášení
=============

Při upgradu balíčků nebo změnách čísel verzí se stává, že dojde ke konfliktu. Jeden balíček má požadavky, které jsou v rozporu s jiným a podobně. Composer ale občas vypisuje plané hlášení. Hlásí konflikt, který reálně neexistuje. V takovém případě pomůže smazat soubor `composer.lock` a zkusit to znovu.

Pokud chybová hláška přetrvává, pak je myšlena vážně a je potřeba z ní vyčíst, co a jak upravit.


Packagist.org - centrální repozitář
===================================

[Packagist |https://packagist.org] je hlavní repozitář, ve kterém se Composer snaží vyhledávat balíčky, pokud mu neřekneme jinak. Můžeme zde publikovat i vlastní balíčky.


Co když nechceme používat centrální repozitář?
----------------------------------------------

Pokud máme vnitrofiremní aplikace, které zkrátka nemůžeme hostovat veřejně, tak si pro ně vytvoříme firemní repozitář.

Více na téma repozitářů [v oficiální dokumentaci |https://getcomposer.org/doc/05-repositories.md#repositories].


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

Zásadní vlastností Composeru je, že poskytuje autoloading pro všechny jím nainstalované třídy, který nastartujete includováním souboru `vendor/autoload.php`.

Nicméně je možné používat Composer i pro načítání dalších tříd i mimo složku `vendor`. První možností je nechat Composer prohledat definované složky a podsložky, najít všechny třídy a zahrnout je do autoloaderu. Toho docílíte nastavením `autoload > classmap` v `composer.json`:

```js
{
	"autoload": {
		"classmap": [
			"src/",      #  zahrne složku src/ a její podsložky
		]
	}
}
```

Následně je potřeba při každé změně spustit příkaz `composer dumpautoload` a nechat autoloadovací tabulky přegenerovat. To je nesmírně nepohodlné a daleko lepší je tento úkol svěřit [RobotLoaderu|robot-loader:], který stejnou činnost provádí automaticky na pozadí a mnohem rychleji.

Druhou možností je dodržovat [PSR-4|https://www.php-fig.org/psr/psr-4/]. Zjednodušeně řečeno jde o systém, kdy jmenné prostory a názvy tříd odpovídají adresářové struktuře a názvům souborů, tedy např. `App\Core\RouterFactory` bude v souboru `/path/to/App/Core/RouterFactory.php`. Příklad konfigurace:

```js
{
	"autoload": {
		"psr-4": {
			"App\\": "app/"   # jmenný prostor App\ je v adresáři app/
		}
	}
}
```

Jak přesně chování nakonfigurovat se dozvíte v [dokumentaci Composeru|https://getcomposer.org/doc/04-schema.md#psr-4].


Testování nových verzí
======================

Chcete otestovat novou vývojovou verzi balíčku. Jak na to? Nejprve do souboru `composer.json` přidejte tuto dvojici voleb, která dovolí instalovat vývojové verze balíčků, avšak uchýlí se k tomu pouze v případě, že neexistuje žádná kombinace stable verzí, která by vyhovovala požadavkům:

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

Dále doporučujeme smazat soubor `composer.lock`, někdy totiž Composer nepochopitelně odmítá instalaci a tohle problém vyřeší.

Dejme tomu, že jde o balíček `nette/utils` a nová verze má číslo 4.0. Nainstalujete ji příkazem:

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

Nebo můžete nainstalovat konkrétní verzi, například 4.0.0-RC2:

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

Když ale na knihovně závisí jiný balíček, který je uzamčený na starší verzi (např. `^3.1`), tak je ideální balík zaktualizovat, aby s novou verzí fungoval.
Pokud však chcete omezení jen obejít a donutit Composer nainstalovat vývojovou verzi a předstírat, že jde o verzi starší (např. 3.1.6), můžete použít klíčové slovo `as`:

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


Volání příkazů
==============

Přes Composer lze volat vlastní předpřipravené příkazy a skripty, jako by šlo o nativní příkazy Composeru. U skriptů, které se nacházejí ve složce `vendor/bin`, není potřeba tuto složku uvádět.

Jako příklad si definujeme v souboru `composer.json` skript, který pomocí [Nette Testeru|tester:] spustí testy:

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

Testy pak spustíme pomocí `composer tester`. Příkaz můžeme zavolat i v případě, že nejsme v kořenové složce projektu, ale v některém podadresáři.


Pošlete dík
===========

Ukážeme vám trik, kterým potěšíte autory open source. Jednoduchým způsobem dáte na GitHubu hvězdičku knihovnám, které váš projekt používá. Stačí nainstalovat knihovnu `symfony/thanks`:

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

A poté spustit:

```shell
composer thanks
```

Zkuste si to!


Konfigurace
===========

Composer je úzce propojený s verzovacím nástrojem [Git |https://git-scm.com]. Pokud jej nemáte nainstalovaný, je třeba Composeru říct, aby jej nepoužíval:

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

{{sitename: Best Practices}}

Composer: tipy pro použití

Composer je nástroj pro správu závislostí v PHP. Umožní nám vyjmenovat knihovny, na kterých náš projekt závisí, a bude je za nás instalovat a aktualizovat. Ukážeme si:

  • jak Composer nainstalovat
  • jeho použití v novém či stávajícím projektu

Instalace

Composer je spustitelný .phar soubor, který si stáhnete a nainstalujete následujícím způsobem:

Windows

Použijte oficiální instalátor Composer-Setup.exe.

Linux, macOS

Stačí 4 příkazy, které si zkopírujte z této stránky.

Dále vložením do složky, která je v systémovém PATH, se stane Composer přístupný globálně:

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

Použití v projektu

Abychom mohli ve svém projektu začít používat Composer, potřebujete pouze soubor composer.json. Ten popisuje závislosti našeho projektu a může také obsahovat další metadata. Základní composer.json tedy může vypadat takto:

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

Říkáme zde, že naše aplikace (nebo knihovna) vyžaduje balíček nette/database (název balíčku se skládá z názvu organizace a názvu projektu) a chce verzi, která odpovídá podmínce ^3.0 (tj. nejnovější verzi 3).

Máme tedy v kořenu projektu soubor composer.json a spustíme instalaci:

composer update

Composer stáhne Nette Database do složky vendor/. Dále vytvoří soubor composer.lock, který obsahuje informace o tom, které verze knihoven přesně nainstaloval.

Composer vygeneruje soubor vendor/autoload.php, který můžeme jednoduše inkludovat a začít používat knihovny bez jakékoli další práce:

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

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

Aktualizace balíčků na nejnovější verze

Aktualizaci použiváných knihoven na nejnovější verze podle podmínek definovaných v composer.json má na starosti příkaz composer update. Např. u závislosti "nette/database": "^3.0" nainstaluje nejnovější verzi 3.x.x, ale nikoliv už verzi 4.

Pro aktualizaci podmínek v souboru composer.json například na "nette/database": "^4.1", aby bylo možné nainstalovat nejnovější verzi, použijte příkaz composer require nette/database.

Pro aktualizaci všech používaných balíčků Nette by bylo nutné je všechny v příkazové řádce vyjmenovat, např.:

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

Což je nepraktické. Použijte proto jednoduchý skript Composer Frontline, který to udělá za vás:

php composer-frontline.php

Vytvoření nového projektu

Nový projekt na Nette vytvoříte pomocí jediného příkazu:

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

Jako nazev-projektu vložte název adresáře pro svůj projekt a potvrďte. Composer stáhne repozitář nette/web-project z GitHubu, který už obsahuje soubor composer.json, a hned potom Nette Framework. Mělo by již stačit pouze nastavit oprávnění na zápis do složek temp/ a log/ a projekt by měl ožít.

Pokud víte, na jaké verzi bude PHP projekt hostován, nezapomeňte ji nastavit.

Verze PHP

Composer vždy instaluje ty verze balíčků, které jsou kompatibilní s verzí PHP, kterou právě používáte (lépe řečeno s verzí PHP používanou v příkazové řádce při spouštění Composeru). Což ale nejspíš není stejná verze, jakou používá váš hosting. Proto je velmi důležité si do souboru composer.json přidat informaci o verzi PHP na hostingu. Poté se budou instalovat pouze verze balíčků s hostingem kompatibilní.

To, že projekt poběží například na PHP 8.2.3, nastavíme příkazem:

composer config platform.php 8.2.3

Takto se verze zapíše do souboru composer.json:

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

Nicméně číslo verze PHP se uvádí ještě na jiném místě souboru, a to v sekci require. Zatímco první číslo určuje, pro jakou verzi se budou instalovat balíčky, druhé číslo říká, pro jakou verzi je napsaná samotná aplikace. A podle něj například PhpStorm nastavuje PHP language level. (Samozřejmě nedává smysl, aby se tyto verze lišily, takže dvojí zápis je nedomyšlenost.) Tuto verzi nastavíte příkazem:

composer require php 8.2.3 --no-update

Nebo přímo v souboru composer.json:

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

Ignorování verze PHP

Balíčky zpravidla mívají uvedenou jak nejnižší verzi PHP, se kterou jsou kompatibilní, tak i nejvyšší, se kterou jsou testované. Pokud se chystáte používat verzi PHP ještě novější, třeba z důvodu testování, Composer odmítne takový balíček nainstalovat. Řešením je volba --ignore-platform-req=php+, která způsobí, že Composer bude ignorovat horní limity požadované verze PHP.

Planá hlášení

Při upgradu balíčků nebo změnách čísel verzí se stává, že dojde ke konfliktu. Jeden balíček má požadavky, které jsou v rozporu s jiným a podobně. Composer ale občas vypisuje plané hlášení. Hlásí konflikt, který reálně neexistuje. V takovém případě pomůže smazat soubor composer.lock a zkusit to znovu.

Pokud chybová hláška přetrvává, pak je myšlena vážně a je potřeba z ní vyčíst, co a jak upravit.

Packagist.org – centrální repozitář

Packagist je hlavní repozitář, ve kterém se Composer snaží vyhledávat balíčky, pokud mu neřekneme jinak. Můžeme zde publikovat i vlastní balíčky.

Co když nechceme používat centrální repozitář?

Pokud máme vnitrofiremní aplikace, které zkrátka nemůžeme hostovat veřejně, tak si pro ně vytvoříme firemní repozitář.

Více na téma repozitářů v oficiální dokumentaci.

Autoloading

Zásadní vlastností Composeru je, že poskytuje autoloading pro všechny jím nainstalované třídy, který nastartujete includováním souboru vendor/autoload.php.

Nicméně je možné používat Composer i pro načítání dalších tříd i mimo složku vendor. První možností je nechat Composer prohledat definované složky a podsložky, najít všechny třídy a zahrnout je do autoloaderu. Toho docílíte nastavením autoload > classmap v composer.json:

{
	"autoload": {
		"classmap": [
			"src/",      #  zahrne složku src/ a její podsložky
		]
	}
}

Následně je potřeba při každé změně spustit příkaz composer dumpautoload a nechat autoloadovací tabulky přegenerovat. To je nesmírně nepohodlné a daleko lepší je tento úkol svěřit RobotLoaderu, který stejnou činnost provádí automaticky na pozadí a mnohem rychleji.

Druhou možností je dodržovat PSR-4. Zjednodušeně řečeno jde o systém, kdy jmenné prostory a názvy tříd odpovídají adresářové struktuře a názvům souborů, tedy např. App\Core\RouterFactory bude v souboru /path/to/App/Core/RouterFactory.php. Příklad konfigurace:

{
	"autoload": {
		"psr-4": {
			"App\\": "app/"   # jmenný prostor App\ je v adresáři app/
		}
	}
}

Jak přesně chování nakonfigurovat se dozvíte v dokumentaci Composeru.

Testování nových verzí

Chcete otestovat novou vývojovou verzi balíčku. Jak na to? Nejprve do souboru composer.json přidejte tuto dvojici voleb, která dovolí instalovat vývojové verze balíčků, avšak uchýlí se k tomu pouze v případě, že neexistuje žádná kombinace stable verzí, která by vyhovovala požadavkům:

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

Dále doporučujeme smazat soubor composer.lock, někdy totiž Composer nepochopitelně odmítá instalaci a tohle problém vyřeší.

Dejme tomu, že jde o balíček nette/utils a nová verze má číslo 4.0. Nainstalujete ji příkazem:

composer require nette/utils:4.0.x-dev

Nebo můžete nainstalovat konkrétní verzi, například 4.0.0-RC2:

composer require nette/utils:4.0.0-RC2

Když ale na knihovně závisí jiný balíček, který je uzamčený na starší verzi (např. ^3.1), tak je ideální balík zaktualizovat, aby s novou verzí fungoval. Pokud však chcete omezení jen obejít a donutit Composer nainstalovat vývojovou verzi a předstírat, že jde o verzi starší (např. 3.1.6), můžete použít klíčové slovo as:

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

Volání příkazů

Přes Composer lze volat vlastní předpřipravené příkazy a skripty, jako by šlo o nativní příkazy Composeru. U skriptů, které se nacházejí ve složce vendor/bin, není potřeba tuto složku uvádět.

Jako příklad si definujeme v souboru composer.json skript, který pomocí Nette Testeru spustí testy:

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

Testy pak spustíme pomocí composer tester. Příkaz můžeme zavolat i v případě, že nejsme v kořenové složce projektu, ale v některém podadresáři.

Pošlete dík

Ukážeme vám trik, kterým potěšíte autory open source. Jednoduchým způsobem dáte na GitHubu hvězdičku knihovnám, které váš projekt používá. Stačí nainstalovat knihovnu symfony/thanks:

composer global require symfony/thanks

A poté spustit:

composer thanks

Zkuste si to!

Konfigurace

Composer je úzce propojený s verzovacím nástrojem Git. Pokud jej nemáte nainstalovaný, je třeba Composeru říct, aby jej nepoužíval:

composer -g config preferred-install dist