Composer existiert seit 2012. Das sind 14 Jahre Dependency Management, Autoloading und reproduzierbare Builds – für alle, die ihn verwenden. Für alle anderen gibt es den Ordner libs/ mit irgendwelchen kopierten Bibliotheken aus dem Jahr 2011, von denen niemand weiß, ob sie noch aktuell sind, welche Version das war, oder wer sie damals reinkopiert hat. Meistens war es jemand, der nicht mehr da ist.

Warum der Umstieg sich lohnt

Composer löst drei Probleme gleichzeitig: Autoloading, Versionierung und Reproduzierbarkeit. Statt langer include-Ketten gibt es einen einzigen require 'vendor/autoload.php'. Statt manuell kopierten Bibliotheksversionen gibt es eine composer.lock, die garantiert, dass alle Entwickler und alle Server exakt dieselben Abhängigkeiten verwenden. Klingt selbstverständlich. Ist es erstaunlich oft nicht.

Der Einstieg: Composer neben dem bestehenden Code

Der erste Schritt muss das bestehende System nicht verändern. Composer wird installiert, eine composer.json wird angelegt, und der Autoloader wird in den Front-Controller eingebunden – zusätzlich zu den bestehenden Includes, nicht stattdessen. Das verändert kein Verhalten, aber es schafft die Grundlage. Niemand muss es wissen. Es funktioniert einfach.

PSR-4-Autoloading für eigenen Code

Der nächste Schritt ist Autoloading für den eigenen Code. Ein Namespace – zum Beispiel App\ – wird auf ein Verzeichnis gemappt. Neue Klassen, die dort entstehen, werden automatisch geladen. Die alten require-Ketten bleiben vorerst bestehen und werden schrittweise ersetzt, wenn die jeweiligen Dateien ohnehin angefasst werden.

Bestehende Abhängigkeiten migrieren

Kopierte Bibliotheken werden schrittweise durch Composer-Pakete ersetzt. Zunächst: Gibt es das Paket auf Packagist? Falls ja, wird die kopierte Version entfernt und durch composer require ersetzt. Falls nein, kann der Code als lokales Paket oder über ein VCS-Repository eingebunden werden. Falls das Paket seit Jahren nicht mehr gepflegt wird: willkommen im nächsten Refactoring-Projekt.

Composer einzuführen bedeutet nicht, alles auf einmal zu ändern. Es bedeutet, ab heute keine neuen Abhängigkeiten mehr zu kopieren.

Häufige Fallstricke

Namenskonflikte zwischen alten global definierten Klassen und neuen Composer-Paketen sind das häufigste Problem. Hier hilft ein klarer Namespace für den eigenen Code, der Konflikte von Anfang an vermeidet. Außerdem: composer.lock gehört ins Repository – immer, auch für Anwendungen, nicht nur für Bibliotheken. Das ist keine Empfehlung, das ist Pflicht.

Fazit

Composer nachträglich einzuführen ist einer der Schritte mit dem besten Aufwand-Nutzen-Verhältnis in der Legacy-Modernisierung. Er öffnet die Tür zu modernen Bibliotheken, zu sauberem Autoloading und zu einem reproduzierbaren Build-Prozess – ohne das bestehende System von einem Tag auf den anderen zu verändern. Und man kann endlich aufhören, Bibliotheken zu kopieren wie im Jahr 2009.