Composer in Legacy-Projekten: Abhängigkeiten managen wenn kein Composer existiert

Sie öffnen den Ordner Ihrer PHP-Anwendung und finden ein Verzeichnis namens lib, includes oder vendor_old. Darin liegen PHPMailer, eine PDF-Bibliothek und ein Datumsparser. Alle irgendwann 2014 heruntergeladen, entpackt und hineinkopiert. Niemand weiß, welche Version das ist. Niemand hat seitdem ein Update eingespielt. Composer in einem Legacy-PHP-Projekt nachzurüsten ist genau für diesen Fall gedacht. Der Weg dorthin ist weniger aufwendig, als viele befürchten.
Composer ist der Paketmanager für PHP. Er lädt Bibliotheken in einer festgelegten Version herunter und löst deren Abhängigkeiten auf. Geladen werden sie dann über eine zentrale Datei. Seit 2012 ist er der Standard. Viele Anwendungen sind aber älter oder wurden von Entwicklern gebaut, die ihn nie eingeführt haben. Das ist kein Vorwurf. Manuelles Kopieren war damals üblich und hat funktioniert.
Warum manuell kopierte Bibliotheken zum Problem werden
Solange die Anwendung läuft, fällt das Thema nicht auf. Es meldet sich erst, wenn etwas passiert.
Sicherheitslücken bleiben unbemerkt
PHPMailer zum Beispiel hatte in den letzten Jahren mehrere kritische Lücken. Für die aktuellen Versionen wurden sie geschlossen. Die Kopie in Ihrem lib-Ordner hat davon nichts mitbekommen. Sie wissen nicht einmal, welche Version dort liegt, also können Sie die Lücke nicht einordnen. Werkzeuge wie composer audit, die bekannte Schwachstellen automatisch melden, haben ohne Composer nichts zu prüfen. Wie sich ungepflegte Abhängigkeiten im Alltag rächen, haben wir an anderer Stelle ausführlich beschrieben. Bei npm-Paketen sieht das Bild ganz ähnlich aus.
Updates werden zur Handarbeit mit Risiko
Wer eine kopierte Bibliothek aktualisieren will, tauscht Dateien von Hand aus. Dabei geht oft etwas schief. Vielleicht hat jemand vor Jahren eine Zeile direkt in der Bibliothek geändert. Ein Workaround für einen Fehler. Diese Änderung ist nach dem Austausch weg. Die Anwendung bricht an einer Stelle, die niemand mit dem Update in Verbindung bringt.
Das PHP-Upgrade wird blockiert
Alte Bibliotheken nutzen Funktionen, die in PHP 8 nicht mehr existieren. Ohne Composer ist unklar, welche Bibliothek in welcher Version betroffen ist. Jede PHP-Modernisierung beginnt deshalb mit der Frage: Welche Fremdbibliotheken stecken eigentlich in diesem Projekt? Wer das nicht beantworten kann, schätzt den Aufwand falsch.
Lizenzfragen bleiben offen
Open-Source-Bibliotheken haben Lizenzen. Manche verlangen einen Hinweis, manche schließen bestimmte Nutzungen aus. Mit Composer lassen sich alle Lizenzen per Befehl auflisten. Bei kopierten Ordnern müssen Sie jede Bibliothek einzeln nachschlagen. Welche Pflichten Unternehmen beim Einsatz von Open Source haben, erklärt ein eigener Artikel.
Composer nachträglich einführen: Schritt für Schritt
Die gute Nachricht zuerst: Sie müssen die Anwendung nicht umschreiben. Composer lässt sich neben dem bestehenden Code einführen. Der alte Code bleibt, wo er ist. Nur die Bibliotheken wechseln nach und nach den Ort.
Schritt 1: Bestandsaufnahme der Bibliotheken
Suchen Sie im Projekt nach Fremdcode. Typische Orte sind lib, libs, includes, classes, vendor und third_party. Für jede gefundene Bibliothek notieren Sie Name und Version. Die Version steht oft in einer README, einem CHANGELOG oder im Kopf der Hauptdatei. Fehlt sie, hilft ein Vergleich mit den Releases auf GitHub.
Prüfen Sie außerdem, ob jemand die Bibliothek verändert hat. Ein Diff gegen die Originalversion zeigt das schnell. Solche Änderungen sind wichtig. Sie müssen später als Patch oder Wrapper erhalten bleiben.
Schritt 2: composer.json anlegen
Im Projektstamm legen Sie eine Datei composer.json an. Sie beschreibt, welche Pakete das Projekt braucht. Anfangs kann sie fast leer sein. Wichtig ist, dass composer install einmal durchläuft und einen vendor-Ordner mit der Datei vendor/autoload.php erzeugt.
Falls bereits ein Ordner vendor mit handkopierten Bibliotheken existiert, benennen Sie ihn vorher um. Sonst überschreibt Composer Dateien, die Sie noch brauchen.
Schritt 3: Autoloader einbinden
Der Autoloader ist die Datei, die PHP sagt, wo welche Klasse liegt. Binden Sie require __DIR__ . '/vendor/autoload.php'; in Ihre zentrale Einstiegsdatei ein. Das ist meist index.php, bootstrap.php oder eine config.php, die überall geladen wird.
Danach passiert erst einmal nichts Sichtbares. Alle alten require-Zeilen funktionieren weiter. Genau das ist das Ziel. Composer läuft jetzt mit, ohne etwas zu verändern.
Schritt 4: Eine Bibliothek nach der anderen ersetzen
Jetzt beginnt die eigentliche Arbeit. Nehmen Sie die Bibliothek mit dem höchsten Sicherheitsrisiko zuerst. PHPMailer ist ein typischer Kandidat. Installieren Sie die aktuelle Version per composer require phpmailer/phpmailer.
Dann entfernen Sie die alte require-Zeile, die auf den lib-Ordner zeigt. Der Autoloader übernimmt. Testen Sie die betroffenen Funktionen. Bei PHPMailer wäre das jeder Mailversand der Anwendung.
Meist ändern sich zwischen einer Version von 2014 und heute einige Klassennamen oder Methoden. Sie brauchen dann kleine Anpassungen im aufrufenden Code. Diese Änderungen sind überschaubar und gut dokumentiert. Die Upgrade-Hinweise der Bibliothek listen sie auf.
Erst wenn eine Bibliothek vollständig umgestellt ist, löschen Sie die alte Kopie. Nicht vorher.
Schritt 5: Eigene Änderungen retten
Hat jemand direkt in einer Bibliothek etwas verändert, gibt es zwei saubere Wege. Der erste ist ein Patch, den Composer bei jeder Installation automatisch anwendet. Dafür gibt es das Plugin cweagans/composer-patches. Der zweite Weg ist eine eigene Klasse, die von der Bibliotheksklasse erbt. Sie überschreibt nur die eine Methode. Der zweite Weg ist meist stabiler.
Schritt 6: composer.lock einchecken und Pipeline anpassen
Composer erzeugt eine Datei composer.lock. Sie hält exakt fest, welche Versionen installiert sind. Diese Datei gehört in die Versionsverwaltung. Der vendor-Ordner dagegen nicht mehr. Ihr Deployment muss ab jetzt composer install ausführen. Das ist meist eine Zeile im Build-Skript.
Wenn eine Bibliothek nicht auf Packagist liegt
Nicht jede alte Bibliothek gibt es als Composer-Paket. Manche Projekte sind seit Jahren verwaist. Dafür gibt es drei Möglichkeiten.
Sie können den Code als lokales Paket einbinden. Composer unterstützt sogenannte Path-Repositories. Die Bibliothek bleibt im Projekt, bekommt aber eine eigene composer.json und läuft über den Autoloader.
Sie können nach einem Nachfolger suchen. Für die meisten verwaisten Bibliotheken existiert ein gepflegter Fork oder eine moderne Alternative mit ähnlicher Schnittstelle.
Oder Sie schreiben den betroffenen Teil neu. Das lohnt sich bei kleinen Helfern mit wenigen hundert Zeilen. Ein Datumsparser aus 2010 lässt sich heute oft durch eine eingebaute PHP-Funktion ersetzen.
Typische Fehler beim Umstieg
Der häufigste Fehler ist der Versuch, alles an einem Wochenende umzustellen. Das geht fast immer schief. Zehn Bibliotheken gleichzeitig zu tauschen bedeutet, dass zehn Fehlerquellen gleichzeitig auftreten können. Nehmen Sie sich pro Bibliothek einen eigenen Schritt vor, mit eigenem Test und eigenem Commit.
Der zweite Fehler ist das Löschen der alten Ordner, bevor alles getestet ist. Behalten Sie die Kopien, bis die Anwendung mindestens eine Woche im Betrieb stabil läuft.
Der dritte Fehler betrifft composer update in Produktion. Dieser Befehl holt die neuesten Versionen und kann Verhalten verändern. In Produktion gehört nur composer install, das genau die Versionen aus der Lock-Datei einspielt.
Was der Umstieg bringt
Nach der Umstellung wissen Sie jederzeit, welche Fremdbibliothek in welcher Version läuft. Ein Befehl zeigt offene Sicherheitslücken. Ein weiterer zeigt verfügbare Updates. Das PHP-Upgrade wird planbar, weil die Abhängigkeiten sichtbar sind. Und wer das Projekt als Nächstes übernimmt, findet sich in einer Stunde zurecht. Nicht erst nach einer Woche.
Was sich über Jahre in einem lib-Ordner angesammelt hat, lässt sich in wenigen Wochen abtragen. Eine Neuentwicklung braucht es dafür nicht, und die Anwendung läuft die ganze Zeit weiter.
Fazit
Composer in Legacy-PHP-Projekten nachträglich einzuführen kostet wenig und bringt viel. Der Code bleibt. Die Anwendung läuft weiter. Nur die Abhängigkeiten wandern an einen Ort, an dem sie sich pflegen lassen.
Sie haben so einen lib-Ordner und wissen nicht, was drin steckt? Wir schauen uns das an und sagen Ihnen, was der Umstieg konkret kostet. Sprechen Sie uns an. Das Erstgespräch ist kostenlos. Mehr zu unserer laufenden Betreuung finden Sie unter Software-Wartung, mehr zum Versionswechsel unter PHP-Upgrade.


