Composer
K čemu je to dobré?
- nástroj na správu závislostí v PHP.
- určíte na jakých knihovnách závisí vaše aplikace a composer se postará o potřebné verze
- správa balíčků pro každý projekt zvlášť (adresář
vendor)
instalace
composer.json (format)
composer init{
"name": "author/my-project",
"description": "My project",
"type": "project",
"authors": [
{
"name": "Vojtěch Jirkovský",
"email": "jirkovoj@fit.cvut.cz"
}
],
"require": {}
}omezení verzí balíčků
- verze balíčků se řídí sémantickým verzováním –
MAJOR.MINOR.PATCHMAJOR– zpětně nekompatibilní změnaMINOR– nová funkcionalita, zpětně kompatibilníPATCH– oprava chyby
- v
requirese neuvádí konkrétní verze, ale omezení (constraint) – rozsah verzí, které aplikaci vyhovují omezení doplní
composer requireautomaticky (zpravidla^)"require": { "symfony/validator": "^7.3", "tracy/tracy": "~2.10.0", "nette/utils": "4.*", "some/package": "1.2.3" }^7.3– caret, nejčastější volba: vše až do dalšíMAJORverze, tj.>=7.3.0 <8.0.0~2.10.0– tilde, smí se měnit poslední uvedená část, tj.>=2.10.0 <2.11.0(zatímco~2.10znamená>=2.10 <3.0)4.*– jakákoli verze sMAJOR41.2.3– přesně jedna verze; nedoporučeno, blokuje i bezpečnostní opravy- omezení lze i kombinovat –
>=7.3 <8.0,^7.3 || ^8.0 - omezení určuje, co smí nainstalovat
composer update; co se nainstaluje doopravdy přicomposer install, určujecomposer.lock(viz níže) - více viz dokumentace omezení verzí
závislosti pouze pro vývojáře
require– balíčky, které potřebuje samotná aplikace za běhurequire-dev– balíčky potřebné jen při vývoji: testovací frameworky, debuggery, lintery, generátory dokumentacecomposer require --dev phpunit/phpunit"require": { "symfony/validator": "^7.3" }, "require-dev": { "phpunit/phpunit": "^12.0" },composer installnainstaluje obojícomposer install --no-devnainstaluje pouzerequire– použijte při nasazení na produkci (menšívendor, méně cizího kódu na serveru)- kód z
require-devproto nesmí být volán z aplikace – na produkci tam nebude
požadavky na platformu
kromě balíčků se do
requireuvádí i to, co aplikace potřebuje od prostředí – verzi PHP a rozšíření (extensions)"require": { "php": ">=8.3", "ext-gd": "*", "ext-pdo": "*" }php– minimální, případně i maximální verze PHPext-*– vyžadované rozšíření PHP; název odpovídá výpisuphp -mComposer požadavky ověřuje při instalaci a jinak instalaci odmítne:
Problem 1 - Root composer.json requires PHP extension ext-gd * but it is missing from your system.- správné řešení je rozšíření doinstalovat a ověřit pomocí
php -m, že je načtené --ignore-platform-reqskontrolu vypne, ale aplikace pak (nejspíš) spadne až za běhu- co prostředí nabízí, vypíše
composer check-platform-reqs
příkazy
require- přidá novou závislost docomposer.jsonrequire --dev- přidá závislost potřebnou jen pro vývoj (dorequire-dev)remove- odebere závislost zcomposer.jsona smaže ji z adresářevendorinstall- nainstaluje závislosti dlecomposer.locknebocomposer.jsoninstall --no-dev- nainstaluje bez vývojových závislostí (produkční nasazení)update- nainstaluje/aktualizuje závislosti dlecomposer.jsonupdate vendor/balicek- aktualizuje pouze uvedený balíček; ostatní zůstanou na verzích zapsaných vcomposer.lock- hodí se, když potřebujete opravu v jedné knihovně a nechcete sahat na zbytek projektu
dump-autoload- vygenerujevendor/autoload.php(po instalaci balíčků automaticky)
skripty
direktiva
scriptsvcomposer.jsonpojmenuje často používané příkazy"scripts": { "test": "phpunit", "lint": "phpcs src tests", "check": ["@lint", "@test"] },- skript se spustí jako
composer test, případněcomposer run test - hodnotou je jeden příkaz, nebo pole příkazů, které se provedou po sobě
@nazevodkazuje na jiný skript ve stejném souboru- při běhu skriptu je adresář
vendor/binv proměnnéPATH– stačí tedy napsatphpunitmístovendor/bin/phpunit - dostupné skripty vypíše
composer run-script --list - skript lze navázat i na událost Composeru (
post-install-cmd,post-update-cmd, aj.), více viz oficiální dokumentace skriptů
adresář vendor
- obsahuje nainstalované balíčky, vygenerovaný autoloader a spustitelné soubory
do gitu nepatří – jeho obsah je plně rekonstruovatelný příkazem
composer installzcomposer.jsonacomposer.lock# .gitignore /vendor/vendor/bin/– spustitelné soubory balíčků, např.vendor/bin/phpunit- odkaz sem Composer vytvoří podle direktivy
bin, kterou deklaruje balíček - totéž lze spustit i jako
composer exec phpunit
- odkaz sem Composer vytvoří podle direktivy
composer.lock
- zafixované konkrétní verze balíčků pro pozdější
composer install - lze verzovat v gitu či jiném systému
- verzování
composer.lockje doporučeno (prevence neočekávané aktualizace balíčků), viz oficiální dokumentace Composeru či článek na Medium.com
- verzování
composer updatemůže změnitcomposer.lock
autoloading
- pro nainstalované závislosti generuje autoloader (
dump-autoload) lze nastavit i pro vlastní aplikaci, pro aplikaci dodržující standard PSR-4 např.
"autoload": { "psr-4": {"Eshop\\": "src/"} },- Composerem lze automaticky načítat kód i podle jiných pravidel
file: automaticky načte všechny specifikované soubory (př. pro registraci vlastního autoloaderu)classmap: Composer naskenuje všechny existující třídy, vytvoří mapování název třídy → název souboru a autoloader tuto mapu využívá- aj., více viz oficiální dokumentace direktivy
autoload
- po každé změně direktivy
autoloadje nutné autoloader vygenerovat znovu (composer dump-autoload) – sám se obnoví jen při instalaci balíčků autoload-dev– pravidla platná jen při vývoji, typicky jmenný prostor testů"autoload": { "psr-4": {"Eshop\\": "src/"} }, "autoload-dev": { "psr-4": {"Eshop\\Tests\\": "tests/"} },- při
composer install --no-devse tato pravidla do autoloaderu nezahrnou
- při
- v závislosti na aplikaci může být dostačující autoloader vygenerovaný Composerem, případně může být zapotřebí definovat si autoloader i vlastní
optimalizace autoloaderu
- výchozí autoloader PSR-4 odvodí z názvu třídy cestu a při každém hledání ověřuje, zda soubor na disku existuje – to stojí čas
dump-autoload -o(--optimize)- z pravidel PSR-4 předem vygeneruje statickou classmapu (název třídy → soubor), hledání je pak jen pohled do pole
- třída, která v mapě není (např. přidaná až po vygenerování), se stále dohledá podle pravidel PSR-4
dump-autoload -a(--classmap-authoritative)- zahrnuje
-oa navíc prohlásí classmapu za úplnou: co v ní není, autoloader rovnou považuje za neexistující a na disk se už nepodívá - nejrychlejší varianta, ale po přidání každé nové třídy je nutné autoloader vygenerovat znovu
- nepoužitelné, pokud aplikace generuje třídy až za běhu
- zahrnuje
- obě volby patří na produkci (
composer install --no-dev -o); při vývoji je vynechte, jinak vás každá nová třída donutí spustitdump-autoload - více viz dokumentace optimalizace autoloaderu
packagist
- repozitář balíčků pro composer
- na titulní stránce zároveň rychlokurz composeru
- http://packagist.org