PHP Composer ist das Rückgrat moderner PHP-Entwicklung: ein Abhängigkeitsmanager, der die Bibliotheken herunterlädt, die dein Projekt benötigt, ihre Versionen verwaltet und deine Klassen automatisch lädt. Was NPM für JavaScript leistet, leistet Composer für PHP. In diesem Leitfaden behandeln wir alles, was du im Alltag brauchst — von der Installation von Composer über das Hinzufügen von Paketen mit require bis hin zur Logik von composer.lock und dem PSR-4-Autoloading — mit echten, funktionierenden Beispielen.
Was ist Composer und warum brauchst du es?
Früher bedeutete die Nutzung einer PHP-Bibliothek, Dateien von Hand herunterzuladen und sie einzeln mit require einzubinden. Dieser Ansatz war fehleranfällig und machte Versions-Upgrades zum Albtraum. Composer löst drei Kernprobleme:
- Abhängigkeitsauflösung: Es findet automatisch die anderen Pakete, die ein Paket benötigt (und deren Abhängigkeiten) und installiert kompatible Versionen.
- Versionsverwaltung: Du legst fest, welche Versionen akzeptabel sind, und Composer wählt die beste aus, die dieser Regel entspricht.
- Autoloading: Es lädt deine Klassen und Pakete anhand ihres Namens, ohne dass du jede Datei manuell mit
requireeinbinden musst.
Pakete werden aus einem zentralen Repository namens Packagist (packagist.org) bezogen. Das gesamte Ökosystem — Laravel, Symfony, Guzzle, PHPUnit — wird von dort verteilt.
Installation und dein erstes Projekt
Du kannst Composer je nach Betriebssystem installieren: Es gibt ein offizielles Installationsskript für Linux/macOS und einen fertigen Installer für Windows. Zur Überprüfung der Installation:
composer --version
Beim Start eines neuen Projekts kannst du einen interaktiven Assistenten ausführen oder direkt eine composer.json erzeugen:
composer init
Dieser Befehl fragt nach Paketname, Beschreibung, Lizenz und ersten Abhängigkeiten und erstellt anschließend eine composer.json-Datei im Stammverzeichnis. Diese Datei ist der Ausweis deines Projekts; Abhängigkeiten, Autoload-Regeln und Metadaten werden hier gespeichert.
Pakete installieren: require und install
Der direkteste Weg, ein Paket hinzuzufügen, ist der Befehl require. Um beispielsweise den beliebten HTTP-Client Guzzle zu installieren:
composer require guzzlehttp/guzzle
Das lädt das Paket herunter, fügt es zu composer.json hinzu, aktualisiert composer.lock und legt es im Ordner vendor/ ab. Du kannst auch eine Versionsbeschränkung festlegen:
composer require guzzlehttp/guzzle:^7.5
Füge Werkzeuge, die nur in der Entwicklung benötigt werden (Test-Bibliotheken, Code-Analysatoren), mit --dev hinzu; diese werden bei Produktionsinstallationen ausgeschlossen:
composer require --dev phpunit/phpunit
Wenn du ein Projekt klonst, verwendest du install, um seine Abhängigkeiten einzurichten. Dieser Befehl liest die exakten Versionen aus composer.lock und installiert sie originalgetreu:
composer install
Auf einem Produktionsserver lautet die übliche Kombination, um Entwicklungsabhängigkeiten zu überspringen und den Autoload zu optimieren:
composer install --no-dev --optimize-autoloader
composer.json gegen composer.lock
Die Rollen dieser beiden Dateien zu verwechseln ist die häufigste Quelle der Verwirrung. composer.json beschreibt deine Absicht: „jede 7.x-Version von Guzzle ist in Ordnung“. composer.lock hält die aktuelle Realität fest: „Guzzle 7.8.1 wurde installiert, genau“. Ein typischer require-Abschnitt sieht so aus:
{
"require": {
"php": "^8.2",
"guzzlehttp/guzzle": "^7.5",
"monolog/monolog": "^3.0"
},
"require-dev": {
"phpunit/phpunit": "^11.0"
}
}
Die Bedeutung der Versionsoperatoren ist entscheidend:
^7.5— 7.5 und höher, aber kleiner als 8.0. Der gängigste Operator „kompatible Updates erlauben“.~7.5— 7.5 und höher, aber kleiner als 7.6 (nur Patch-Releases).7.5.*— jeder Patch der 7.5-Serie.
Goldene Regel: Füge composer.lock immer der Versionskontrolle (Git) hinzu. So installieren alle im Team und der Produktionsserver dieselben Versionen, was „Bei mir hat es funktioniert“-Probleme verhindert.
Wann update und wann install?
Die Unterscheidung zwischen beiden ist das Herzstück der Abhängigkeitsverwaltung. composer install bleibt der Lock-Datei treu und ändert keine Versionen. composer update hebt Pakete auf die neuesten kompatiblen Versionen an, die composer.json erlaubt, und schreibt composer.lock neu:
composer update
Wenn du nur ein einzelnes Paket aktualisieren möchtest, nenne es:
composer update monolog/monolog
Führe composer update niemals auf einem Produktionsserver aus. Da dieser Befehl Versionen ändert, kann er unerwartete Ausfälle in einer Live-Umgebung verursachen. Führe das Update lokal durch, teste es, committe die neue composer.lock und führe auf dem Server nur composer install aus.
Autoloading: deine eigenen Klassen mit PSR-4
Die mächtigste Funktion von Composer ist das Autoloading. Damit Composer auch deine eigenen Klassen lädt, füge eine PSR-4-Zuordnung zu composer.json hinzu. Diese bindet ein Namespace-Präfix an einen Ordner:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
Diese Zuordnung bedeutet: Die Klasse App\Services\Mailer wird in src/Services/Mailer.php gesucht. Nach dem Hinzufügen der Zuordnung musst du die Autoload-Karte neu erzeugen:
composer dump-autoload
Nun genügt eine einzige Zeile am Einstiegspunkt deines Projekts. Durch das Einbinden des von Composer erzeugten Autoloaders werden sowohl deine eigenen Klassen als auch alle Pakete automatisch geladen:
require __DIR__ . '/vendor/autoload.php';
use App\Services\Mailer;
$mailer = new Mailer();
Für die Performance in der Produktion berechnet das Flag --optimize-autoloader (oder -o) die Klasse-zu-Datei-Zuordnung im Voraus und beseitigt so Dateisystem-Suchvorgänge zur Laufzeit.
Automatisierung mit Composer-Skripten
Der Abschnitt scripts in composer.json erlaubt es dir, Abkürzungen für häufig ausgeführte Befehle zu definieren:
{
"scripts": {
"test": "phpunit",
"check": [
"@php -l src/",
"phpunit"
]
}
}
Du führst sie mit composer test oder composer check aus. Ereignis-Hooks wie post-install-cmd dienen auch dazu, nach der Installation automatische Aufgaben auszulösen — Laravel, das nach der Einrichtung einen Schlüssel generiert, ist ein Beispiel dafür.
Häufige Fragen
Soll ich composer.lock in Git committen?
Ja, unbedingt. In Anwendungsprojekten sollte composer.lock immer committet werden; das garantiert, dass jeder Entwickler und der Produktionsserver exakt dieselben Versionen installieren. Nur wenn du eine Bibliothek (ein Paket) für andere entwickelst, ist es eine übliche Wahl, composer.lock nicht zu committen.
Ich erhalte einen „Class not found“-Fehler — warum?
Die häufigste Ursache ist eine veraltete Autoload-Karte. Wenn du einen neuen PSR-4-Namespace hinzugefügt oder Dateien/Ordner umbenannt hast, führe composer dump-autoload aus. Stelle außerdem sicher, dass der Namespace exakt zum Dateipfad und zum Klassennamen passt, einschließlich Groß- und Kleinschreibung.
Was ist der Unterschied zwischen require und require-dev?
require enthält Pakete, die die Anwendung in jeder Umgebung zum Laufen benötigt. require-dev enthält Werkzeuge, die nur während der Entwicklung benötigt werden (PHPUnit, statische Analyse, Debugger). In der Produktion überspringt composer install --no-dev diese Entwicklungsabhängigkeiten, wodurch die Installation schlanker und sicherer wird.
Ist die Abhängigkeitsverwaltung in deinem PHP-Projekt zum Wirrwarr geworden? Wenn du Hilfe bei der Composer-Einrichtung, der Autoload-Konfiguration, Versionskonflikten oder einer sauberen Architektur für ein Laravel/Symfony-basiertes Projekt brauchst, nimm Kontakt mit mir auf — lass uns gemeinsam ein solides Fundament für dein Projekt schaffen.