Composer
Composer je nástroj na správu závislostí v PHP. Dovoluje nám deklarovat libovolně složité závislosti jednotlivých knihoven a pak je za nás nainstaluje do našeho projektu. Ukážeme si
- jak Composer nainstalovat
- použití v novém či stávajícím projektu
- vytvoření a publikace vlastního balíčku
Instalace
Composer se distribuuje jako spustitelný .phar
soubor a poslední stable si můžete stáhnout zde.
Linux
Pokud používáte Linux, je doporučováno si stáhnout Composer přes installer
$ curl -s https://getcomposer.org/installer | php
Vložením do složky, která je v systémovém PATH
$ mv ./composer.phar ~/bin/composer # nebo /usr/local/bin/composer
se stane composer přístupný globálně pod jednoduchým příkazem
$ composer
Mac OS X
Pro uživatele Macu je doporučováno nainstalovat Composer pomocí Homebrew
$ brew tap josegonzalez/php
$ brew install composer
Je možné, že nemáte v systému nainstalované PHP, takže před instalací Composeru ještě zadáme
$ brew install php54
Nyní již můžete v Terminálu rovnou spouštět příkaz:
$ composer
Pokud z nějakého důvodu Homebrew použít nemůžete, nebo nechcete, tak postupujte úplně stejně jako na linuxovém stroji.
Windows
Doporučuje se použít instalátor, který Composer nabízí na svých stránkách.
Konfigurace
Composer je úzce propojený s verzovacím nástrojem Git. Pokud jej nemáte nainstalový, je třeba Composeru říct, aby jej nepoužíval:
$ composer -g config preferred-install dist
Vytvoření nového projektu
Nový projekt na Nette s ním vytvoříte pomocí jediného příkazu
$ composer create-project nette/sandbox nazev-projektu
Místo nazev-projektu
si doplňte vhodné pojmenování a potvrďte. Composer naklonuje repozitář
nette/sandbox
z Githubu a hned potom stáhne 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.
Packagist.org – centrální repozitář
Packagista 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, tak jako Nette.
Nejsnadnější způsob, jak balíček publikovat, je nahrát ho na Github a jeho url pak vložit do Packagisty. Jak se balíček vytváří si ukážeme za chvilku.
Použití
Základem pro jakýkoliv projekt nebo knihovnu, která využívá Composer, je soubor composer.json
, který
obsahuje meta informace o projektu či knihovně a jejich závislostech.
Náš základní composer.json
tedy může vypadat takto
{
"require": {
"php" : ">=5.3.2",
"nette/nette": "~2.1.0"
}
}
Říkáme zde, že naše aplikace (nebo knihovna) vyžaduje balíček nette/nette
a chce nejnovější verzi,
která odpovídá ~2.1.0
(tj. nejnovější setinkovou verzi Nette 2.1), a taky že běží pouze na PHP
5.3.2
a novějším.
Máme tedy v kořenu projektu soubor composer.json
a spustíme instalaci
$ composer update
Composer stáhne Nette a vloží ho do složky vendor/nette/nette
.
Pokud použijete aktuální nette/sandbox
, tak zde je již tohle vyřešené a základní
composer.json
je již v distribuci obsažen.
Lock soubor
Při instalaci vždy Composer vytvoří zámek composer.lock
, hned vedle composer.json
. Tento soubor
obsahuje jednotlivé verze nainstalovaných balíčků.
Je standardem, že composer.lock
commitujeme do repozitáře pouze u konkrétních aplikací a u knihoven
nikoliv. Mohla by totiž nastat situace, kdy se vydá nová verze a kolega si stáhne aplikaci, zavolá
$ composer install
a bude mít novější verze knihoven. Lock soubor tomu zabraňuje, protože při instalaci se
Composer vždy snaží použít verze uvedené v zámku.
Pokud si chceme vynutit aktualizaci knihoven, stačí jednoduše zavolat $ composer update
.
Co když nechceme používat centrální repozitář?
Pokud máme vnitrofiremní aplikace, které zkrátka nemůžeme hostovat na Githubu, tak aby jsme si je mohli instalovat přes Composer, tak si můžete jednoduše nadefinovat vlastní repozitáře pro projekt.
Nette Framework je díky centrálnímu repozitáři přístupný vždy, ale ukážeme si definici s jeho repozitářem. V
url
může být libovolná cesta, nebo adresa, která směřuje na git, svn nebo mercurial.
{
"repositories": [
{
"type": "vcs",
"url": "git://github.com/nette/nette.git"
}
],
"require": {
"nette/nette": "~2.1.0",
}
}
Stejně tak umí pracovat s repozitáři PEAR (je třeba uvést jiný typ) a zip soubory (distribuční balíky).
Více na téma repozitářů v oficiální dokumentaci.
Co když už máme projekt rozjetý?
Nepovažujme to prosím za nevýhodu, ale za prostor ke zdokonalení našeho projektu. Composer neumí nainstalovat jenom některé závislosti, je nutné, aby se staral o všechny závislosti, které jednotlivé balíčky vyžadují.
Doporučovaný postup tedy je vytvořit si v projektu composer.json
s informacemi o vyžadovaných
balíčcích, závislosti nainstalovat a pak smazat přebývající knihovny v libs/
.
Vlastní balíčky
Za balíček se dá automaticky považovat jakýkoliv projekt, který má v kořenu composer.json
. Ovšem aby se
taková knihovna dala použít jako validní závislost, má povinné dvě pole, name
a version
.
{
"name": "MojeJmeno/Blog",
"description" : "Nejlepší blog",
"version": "1.0.0"
}
Jméno se skládá z poskytovatele (vendor) a z konkrétního balíčku, což bylo zavedeno kvůli konfliktům.
Pokud používáme verzovací systém (například Git), tak není vůbec nutné verzi uvádět. Composer si umí sám přečíst jaké jsou v projektu tagy a větve a detekuje, co z toho vypadá jako verze a je možné si to zvolit jako závislost.
Autoloading
Composer za nás řeší i autoloading. Každá knihovna může v composer.json
uvést, jaký standard používá
a Composer se přizpůsobí. Řekněme tedy, že bude používat PSR-0, náš hlavní namespace bude MojeJmeno
a bude
v podsložce libs.
{
"autoload": {
"psr-0": {"MojeJmeno": "libs/"},
}
}
Co když ale PSR-0 tak docela nedodržujeme? Žádný problém, stačí uvést classmap
místo
psr-0
, což je ekvivalent RobotLoaderu z Nette.
{
"autoload": {
"classmap": ["src/", "lib/"]
}
}
Všechny tyto informace si Composer převede do jedné mapy namespace => složka
a pak nám z toho generuje
autoloader, pro všechny knihovny, které mu sdělily, jak je možné je načítat.
Použití autoloaderu z Composeru
Po nainstalování závislostí Composerem do připraveného sandboxu se musíme pouze zbavit načítání složky
libs/
pomocí RobotLoader
u.
->addDirectory(LIBS_DIR)
A vše by mělo fungovat jak má.