Composer & Packagist


Erfinde das Rad nicht neu. Eine ziemlich irdische Weisheit, die aber in den weiten der PHP-Galaxis ganz besonders gilt. Wenn es ein Klischee über Entwickler gibt, an dem wirklich eine ganze Menge Warheit zu finden ist, dann ist es die Behauptung, wir Entwickler würden dazu neigen, am liebsten alles selber zu machen. Meine Anwendung benötigt eine Template-Engine? Ich bau mir eine. Logging? Ich schreibe schnell eine Klasse dafür.

Um es gleich vorweg zu nehmen: Es gibt gute Gründe für diese Einstellung. Wenn man etwas selber entwickelt, ist man meist auch gleich Experte im Umgang damit. Wenn etwas nicht funktioniert, kann man das Problem sofort suchen und gegebenenfalls eine Lösung entwickeln. Man muss nicht erst einen Fehler melden und versuchen, einen Bugfix für fremden Code zu schreiben, von dem man nicht weiß, ob und wann er in den Code übernommen wird. Man kann außerdem optimierten Code schreiben - Code, der genau auf die eigenen Anforderungen angepasst ist. Code, der klein und übersichtlich bleibt. Und man muss sich nicht erst in die Werke Dritter einarbeiten. Manchmal kann es schneller gehen, etwas eben neu zu machen, als erst lange nach einer ungefähr passenden Drittlösung zu suchen, diese zu erlernen und an die eigenen Bedürfnisse anzupassen. Außerdem ist man offensichtlich nicht auf Dritte angewiesen. Es kann nicht passieren, dass der Entwickler das Projekt aufgibt, obwohl sie auf Support angewiesen sind.

Daher ist eine gewisse Skepsis durchaus angebracht. Ich habe mir allerdings sagen lassen, dass die Situation heute im Vergleich zu früher schon ganz passabel ist. Populäre, moderne PHP-Bibliotheken wie man sie vielzählig auf GitHub findet, sind meist ordentlich dokumentiert, besitzen eine annehmbare Code-Qualität und dank GitHub kann man Bugs einfach melden und den Enwticklern Code-Überarbeitungen auf einfache Art und Weise bereitstellen. Dennoch garantiert niemand, dass ein Projekt nicht irgendwann aufgegeben wird. Bei kleineren Hobby-Projekten ist das etwas, womit man rechnen muss.

Dennoch sollte man Rad nicht neu erfinden. Zumindest nicht, wenn man nicht nach bestem Wissen und Gewissen sagen kann, dass es notwendig ist. Man findet auf GitHub unzählige Repositiorien mit PHP-Bibliotheken zu so ziemlich alles. Darunter sind einige, die von tausenden von Entwicklern benutzt werden und dementsprechend eine Menge Sterne vorzuweisen haben. Ein Stern bedeutet, dass das Repositiorum von einem GitHub-User zu dessen Favoriten hinzugefügt wurde. Sucht man also eine bestimmte Bibliothek, so gebe man einfach ihren Namen mit den naheliegenden Stichwörtern "PHP" und "GitHub" bei einer Suchmaschine ein und evaluiere den Nutzen der so gefundenen Projekte.

Composer



Der klassische und falsche Weg, ein solches Projekt nun in der eigenen Anwendung zu nutzen, wäre, den Code herunterzuladen und ins Verzeichnis der eigenen Applikation zu kopieren. Das ist der breite und schöne Weg, der direkt zur Hölle führt. Oder zur dunklen Seite der Macht. Jedenfalls zu nichts Gutem.

Denn zum einen erhalten wir keine Updates. Zum zweiten sind moderne Projekte schlank. Wenn wir einen Logger einbinden möchten, benötigt der vielleicht selber eine bestimmte Bibliothek für den Dateizugriff. Die liefert er aber nicht mit - heißt, auch darum müssten wir uns kümmern: Herunterladen, einbinden, updaten. Was, wenn es verschiedene Versionen gibt, zum Beispiel in Abhängigkeit von unserer PHP-Version? Dann müssen wir die richtig wählen. Was, wenn die Bibliothek eine Installation benötigt? Dann müssen wir diese manuell aufrufen. Und nun stelle man sich das mal mit zwanzig solcher Bibliotheken vor. Klingt nach einer Sith-Foltermethode, nicht wahr?

Es hat Jahre gedauert (und evolutionär wenig erfolgreiche Entwicklungen wie Pear hervorgerbracht), bis sich die PHP-Community auf eine einzige Lösung hat einigen können. Diese heißt Composer. Composer ist der "Dependency Manager" für PHP. Man könnte auch sagen: Paket-Manager. Composer kümmert sich um all die Probleme, die eben aufgezählt wurden. Download, Wahl der richtigen Version, Installation von Abhängigkeiten (die "Dependencies" - also die Fremdbibliotheken, die eine Fremdbibliothek benötigt), Updates, Installation und noch einiges mehr. Inbesondere Autoloading ist ebenfalls etwas, das Composer gut beherrscht.

Composer installieren



Die Dokumentation von Composer deckt das Thema Installation ab. Es gibt verschiedene Möglichkeiten, Composer zu installieren. Per PHP, per Windows-Installer oder in dem man es manuell herunter lädt. Geht man diesen Weg, erhält man eine Datei namens composer.phar. Die Endung steht dabei für PHP-Archiv. Im Grunde ist die Datei also nur eine zusammengepackte PHP-Anwendung. Die einfachste Vorgehensweise ist, diese Datei nun in alle Projekte zu kopieren, in denen man Composer nutzen möchte. Alternativ kann man Composer auch konventionell installieren - dann muss die Datei nicht in jedes Projekt kopiert werden. Der Vorteil am manuellen Kopieren ist, dass Composer an das Projekt und nicht an das System gebunden ist. Das heißt, wenn man das Projekt an einem anderem System arbeitet, kann man Composer dennoch sofort nutzen.

Um letzters zu tun, benötigt man Zugriff auf eine Konsole. Anhänger des Linux-Kults wissen vermutlich wie das geht, Windows-Kultisten hilft der Aufruf des Ausführen-Dialogs (in der Startleiste beziehungsweise App-Übersicht zu finden) und die Eingabe des Befehls cmd. Dann muss man noch in das Projektverzeichnis wechseln und kann Composer mit php composer.phar aufrufen.

Packagist



Ehe wir mit Composer tatsächlich etwas tun, gibt es eine kleine extraplanetare Mission zum Planeten Packagist. Packagist ist sozusagen der wichtigste Kommunikationsoffizier von Composer. Es verrät Composer, wo es die Bibliotheken, die wir installieren wollen, herunterladen kann. Es verlinkt also beispielsweise zu einem GitHub-Repositorum.

Wenn wir selber Bibliotheken so veröffentliche wollen, dass sie via Composer installiert werden können, müssen wir sie daher bei Packagist registriern. Dazu melden wir uns bei Packagist an (auch per praktischem GitHub-Login möglich), klicken auf den Submit-Button und geben dann die URL an, unter der das Repositiorum zu finden ist. Das kann wie gesagt eine GitHub-URL sein.

Etwas fehlt allerdings noch: Projekte, die in irgend einer Weise mit Composer arbeiten, benötigen eine Konfigurationsdatei. Diese trägt den Namen composer.json. Es handelt sich also um eine JSON-Datei. JSON steht für JavaScript Object Notation, also ein Datenformat. Es zeichnet sich durch seine Einfachheit aus.

In dieser Datei kann man einerseits angeben, welche Abhängigkeiten (Dependencies) das Projekt besitzt. Also mit anderen Worten, welche Bibliotheken installiert werden müssen, damit es ausgeführt werden kann. Insbesondere, wenn man das Projekt aber auf Packagist veröffentlichen möchte, muss man auch Informationen zum Projekt angeben. Man muss und kann dort einiges angeben, wie einen Namen, eine Beschreibung, die Namen der beteiligten Entwickler, die benötigte PHP-Version, und noch einiges mehr. Ein Beispiel:

{
"name": "galaktisches-imperium/todesstern",
"description": "Eine mächtige Waffe mit garantierter Sicherheitslücke",
"keywords": ["raumstation", "laserstrahl"],
"authors": [
{
"name": "Imperiales Planungsbüro"
}
],
"require": {
"php": ">=5.3.7"
"monolog/monolog": "~1.11",
},
"minimum-stability": "dev"
}


Wie man sieht, benötigt die Bibliothek PHP 5.3.7 und installiert außerdem eine weitere Bibliothek, Monolog (ein Logger - loggt garantiert jedes völlig unvorhersehbares Eindringen bemannter Raumflugzeuge in die Raumstation). Der merkwürdige Name ist übrigens gewollt. Er muss eindeutig sein. Daher setzt er sich aus zweit Teilen zusammen: Dem Namen der Entwicklers oder des Team hinter dem Projekt und dem eigentlichen Projektnamen.

Composer nutzen



Wenn wir in einem unserer Projekte Composer nun aber tatsächlich nur zur Paket-Verwaltung nutzen wollen, genügt eine minimale Konfiguration:

{
"require": {
"monolog/monolog": "1.2.*",
}
}

Wir geben im Prinzip nur an, welche Abhängigkeiten bestehen. Die gewünschte Version kann auf verschiedene Weisen angegeben werden. In diesem Beispiel fordern wir die neueste Version des 1.2er-Zweiges an. Um die Installation durchzuführen, rufen wir Composer per Konsole wie folgt auf: php composer.phar install
Die Website bietet eine Übersicht über alle Befehle. Composer versucht nun, alle Anhängigkeiten zu installieren. Die Bibliotheken werden heruntergeladen und im Ordner vendor gespeichert. Außerdem wird ein Autoloader generiert. Auch der wird im Ordner vendor gespeichert. Wenn wir ihn in unsere Anwendung einbinden, müssen wir uns nicht um das Inkludieren der Klassen und Dateien der Fremdbiliotheken kümmern, sondern können Klassen direkt ansprechen. Der Autoloader wird wie folgt eingebunden, wenn sich das einbindende Skript auf oberster Ebene im Projektverzeichnis befindet:
require __DIR__ . '/vendor/autoload.php';

Dank Autoloading müssen wir den Logger nicht mit include oder einem ähnlichen Befehl einbinden, sondern können ihn direkt instanziieren:
$log = new Monolog\Logger('name');


Fazit



Composer ist inzwischen zur Pflicht geworden, wenn es um das Management von Abhängigkeiten geht. Composer lässt sich, sobald die Grundprinzipien einmal verinnerlicht wurden, leicht verwenden. Außerdem lässt spielend leicht in bereits bestehende Projekte integrieren. Voraussetzung ist natürlich, dass Konventionen zur Nutzung von Namensräumen eingehalten werdne, sodass es keine Konflikte mit den von Fremdbibliotheken genutzten Namensräumen geben kann. Composer und Packagist wurden hier nur kurz vorgestellt. Beide sind gut dokumentiert - es empfiehlt sich also, zur weiteren Lektüre die jeweilige Dokumentation zu lesen.

comments powered by Disqus

© 2014-2015 Christoph Konnertz.