Composer: nasveti za uporabo

Composer je orodje za upravljanje odvisnosti v PHP. Omogoča nam, da naštejemo knjižnice, od katerih je naš projekt odvisen, in jih bo za nas nameščal in posodabljal. Pokazali bomo:

  • kako namestiti Composer
  • njegovo uporabo v novem ali obstoječem projektu

Namestitev

Composer je izvedljiva datoteka .phar, ki jo prenesete in namestite na naslednji način:

Windows

Uporabite uradni namestitveni program Composer-Setup.exe.

Linux, macOS

Dovolj so 4 ukazi, ki jih kopirate s te strani.

Nato z vstavitvijo v mapo, ki je v sistemskem PATH, postane Composer dostopen globalno:

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

Uporaba v projektu

Da bi lahko v svojem projektu začeli uporabljati Composer, potrebujete samo datoteko composer.json. Ta opisuje odvisnosti našega projekta in lahko vsebuje tudi druge metapodatke. Osnovni composer.json torej lahko izgleda takole:

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

Tukaj pravimo, da naša aplikacija (ali knjižnica) zahteva paket nette/database (ime paketa sestoji iz imena organizacije in imena projekta) in želi različico, ki ustreza pogoju ^3.0 (tj. najnovejšo različico 3).

Imamo torej v korenu projekta datoteko composer.json in zaženemo namestitev:

composer update

Composer bo prenesel Nette Database v mapo vendor/. Nato bo ustvaril datoteko composer.lock, ki vsebuje informacije o tem, katere različice knjižnic je točno namestil.

Composer bo generiral datoteko vendor/autoload.php, ki jo lahko preprosto vključimo in začnemo uporabljati knjižnice brez kakršnegakoli dodatnega dela:

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

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

Posodabljanje paketov na najnovejše različice

Za posodabljanje uporabljenih knjižnic na najnovejše različice glede na pogoje, definirane v composer.json, skrbi ukaz composer update. Npr. pri odvisnosti "nette/database": "^3.0" bo namestil najnovejšo različico 3.x.x, vendar ne več različice 4.

Za posodobitev pogojev v datoteki composer.json, na primer na "nette/database": "^4.1", da bi bilo mogoče namestiti najnovejšo različico, uporabite ukaz composer require nette/database.

Za posodobitev vseh uporabljenih paketov Nette bi bilo treba vse v ukazni vrstici našteti, npr.:

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

Kar je nepraktično. Uporabite zato preprost skript Composer Frontline, ki to stori za vas:

php composer-frontline.php

Ustvarjanje novega projekta

Nov projekt na Nette ustvarite s pomočjo enega samega ukaza:

composer create-project nette/web-project ime-projekta

Kot ime-projekta vstavite ime mape za svoj projekt in potrdite. Composer bo prenesel repozitorij nette/web-project z GitHuba, ki že vsebuje datoteko composer.json, in takoj zatem Nette Framework. Moralo bi že zadostovati samo nastaviti dovoljenja za pisanje v mape temp/ in log/ in projekt bi moral oživeti.

Če veste, na kateri različici PHP bo projekt gostoval, ne pozabite jo nastaviti.

Različica PHP

Composer vedno namešča tiste različice paketov, ki so združljive z različico PHP, ki jo pravkar uporabljate (bolje rečeno z različico PHP, uporabljeno v ukazni vrstici pri zagonu Composerja). Kar pa najverjetneje ni ista različica, kot jo uporablja vaše gostovanje. Zato je zelo pomembno, da si v datoteko composer.json dodate informacijo o različici PHP na gostovanju. Nato se bodo nameščale samo različice paketov, združljive z gostovanjem.

To, da bo projekt tekel na primer na PHP 8.2.3, nastavimo z ukazom:

composer config platform.php 8.2.3

Tako se različica zapiše v datoteko composer.json:

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

Vendar se številka različice PHP navaja še na drugem mestu datoteke, in sicer v sekciji require. Medtem ko prva številka določa, za katero različico se bodo nameščali paketi, druga številka pravi, za katero različico je napisana sama aplikacija. In po njej na primer PhpStorm nastavlja PHP language level. (Seveda nima smisla, da bi se te različice razlikovale, zato je dvojni zapis nedomišljenost.) To različico nastavite z ukazom:

composer require php 8.2.3 --no-update

Ali neposredno v datoteki composer.json:

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

Ignoriranje različice PHP

Paketi praviloma imajo navedeno tako najnižjo različico PHP, s katero so združljivi, kot tudi najvišjo, s katero so testirani. Če nameravate uporabljati še novejšo različico PHP, na primer zaradi testiranja, bo Composer zavrnil namestitev takšnega paketa. Rešitev je možnost --ignore-platform-req=php+, ki povzroči, da bo Composer ignoriral zgornje meje zahtevane različice PHP.

Lažna sporočila

Pri nadgradnji paketov ali spremembah številk različic se zgodi, da pride do konflikta. En paket ima zahteve, ki so v nasprotju z drugim in podobno. Composer pa včasih izpisuje lažna sporočila. Poroča o konfliktu, ki realno ne obstaja. V takem primeru pomaga izbrisati datoteko composer.lock in poskusiti znova.

Če sporočilo o napaki vztraja, potem je mišljeno resno in je treba iz njega razbrati, kaj in kako urediti.

Packagist.org – centralni repozitorij

Packagist je glavni repozitorij, v katerem Composer poskuša iskati pakete, če mu ne povemo drugače. Tukaj lahko objavimo tudi lastne pakete.

Kaj če ne želimo uporabljati centralnega repozitorija?

Če imamo znotrajpodjetniške aplikacije, ki jih preprosto ne moremo gostovati javno, si zanje ustvarimo podjetniški repozitorij.

Več na temo repozitorijev v uradni dokumentaciji.

Samodejno nalaganje

Ključna lastnost Composerja je, da zagotavlja samodejno nalaganje za vse z njim nameščene razrede, ki ga zaženete z vključitvijo datoteke vendor/autoload.php.

Vendar je mogoče uporabljati Composer tudi za nalaganje drugih razredov izven mape vendor. Prva možnost je, da pustite Composerju preiskati definirane mape in podmape, najti vse razrede in jih vključiti v samodejni nalagalnik. To dosežete z nastavitvijo autoload > classmap v composer.json:

{
	"autoload": {
		"classmap": [
			"src/",      # vključi mapo src/ in njene podmape
		]
	}
}

Nato je treba ob vsaki spremembi zagnati ukaz composer dumpautoload in pustiti, da se tabele samodejnega nalaganja ponovno generirajo. To je izjemno neprijetno in veliko bolje je to nalogo zaupati RobotLoaderju, ki isto dejavnost izvaja samodejno v ozadju in veliko hitreje.

Druga možnost je upoštevati PSR-4. Poenostavljeno rečeno gre za sistem, kjer imenski prostori in imena razredov ustrezajo strukturi map in imenom datotek, torej npr. App\Core\RouterFactory bo v datoteki /path/to/App/Core/RouterFactory.php. Primer konfiguracije:

{
	"autoload": {
		"psr-4": {
			"App\\": "app/"   # imenski prostor App\ je v mapi app/
		}
	}
}

Kako natančno konfigurirati obnašanje, boste izvedeli v dokumentaciji Composerja.

Testiranje novih različic

Želite preizkusiti novo razvojno različico paketa. Kako to storiti? Najprej v datoteko composer.json dodajte ta par možnosti, ki dovoli nameščanje razvojnih različic paketov, vendar se k temu zateče samo v primeru, da ne obstaja nobena kombinacija stabilnih različic, ki bi ustrezala zahtevam:

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

Nato priporočamo izbris datoteke composer.lock, včasih namreč Composer nerazumljivo zavrne namestitev in to težavo reši.

Recimo, da gre za paket nette/utils in nova različica ima številko 4.0. Namestite jo z ukazom:

composer require nette/utils:4.0.x-dev

Ali pa lahko namestite konkretno različico, na primer 4.0.0-RC2:

composer require nette/utils:4.0.0-RC2

Ko pa je od knjižnice odvisen drug paket, ki je zaklenjen na starejšo različico (npr. ^3.1), je idealno paket posodobiti, da bo deloval z novo različico. Če pa želite omejitev samo zaobiti in prisiliti Composer, da namesti razvojno različico in se pretvarja, da gre za starejšo različico (npr. 3.1.6), lahko uporabite ključno besedo as:

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

Klicanje ukazov

Prek Composerja lahko kličete lastne vnaprej pripravljene ukaze in skripte, kot da bi šlo za izvorne ukaze Composerja. Pri skriptih, ki se nahajajo v mapi vendor/bin, ni treba te mape navajati.

Kot primer si definiramo v datoteki composer.json skript, ki s pomočjo Nette Testerja zažene teste:

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

Teste nato zaženemo s pomočjo composer tester. Ukaz lahko pokličemo tudi v primeru, da nismo v korenski mapi projekta, ampak v katerem od poddirektorijev.

Pošljite zahvalo

Pokazali vam bomo trik, s katerim boste razveselili avtorje odprte kode. Na preprost način boste na GitHubu dali zvezdico knjižnicam, ki jih vaš projekt uporablja. Dovolj je namestiti knjižnico symfony/thanks:

composer global require symfony/thanks

In nato zagnati:

composer thanks

Poskusite!

Konfiguracija

Composer je tesno povezan z orodjem za verzioniranje Git. Če ga nimate nameščenega, je treba Composerju povedati, naj ga ne uporablja:

composer -g config preferred-install dist