aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Webentwicklung

PHP PSR-4-Autoloading: Namespace-zu-Verzeichnis-Zuordnung

PHP PSR-4 ist ein Autoloading-Standard, mit dem du Klassen allein anhand ihres Namens aus der richtigen Datei lädst, ohne jemals von Hand require aufzurufen. Die Kernidee passt in einen Satz: Du bindest einen Namespace-Präfix an ein Basisverzeichnis, und die übrigen Namespace-Segmente entsprechen direkt dem Ordnerpfad. In diesem Artikel behandeln wir die Regeln von PSR-4, die Konfiguration über composer.json und die Lösung der typischen Fehler aus dem Alltag, alles mit echten Beispielen.

Warum ist Autoloading nötig?

In den frühen PHP-Jahren musstest du die Datei jeder Klasse vor der Verwendung manuell einbinden. In einem mittelgroßen Projekt füllte sich der Kopf jeder Datei mit Dutzenden require_once-Zeilen, und schon das Verschieben einer einzigen Datei bedeutete, die Pfade Stück für Stück anzupassen. Autoloading nimmt diesen Schmerz weg: Sobald PHP zum ersten Mal auf eine undefinierte Klasse trifft, löst es eine registrierte Rückruffunktion (den Autoloader) aus und lädt die betreffende Datei sofort.

Das Herzstück dieses Mechanismus ist die Funktion spl_autoload_register(). PSR-4 ist ein gemeinsamer Vertrag, der definiert, wie sich der bei dieser Funktion registrierte Autoloader verhalten soll. Der Standard wurde von der PHP-FIG (Framework Interop Group) veröffentlicht, und heute folgt ihm nahezu das gesamte moderne Ökosystem, darunter Laravel, Symfony und Guzzle. Dadurch können verschiedene Bibliotheken einen einzigen Autoloader teilen, und das Ableiten eines Dateipfads aus einem Klassennamen wird vollständig vorhersehbar.

Die Kernregel von PSR-4

Nach PSR-4 besteht ein voll qualifizierter Klassenname aus drei Teilen: einem Namespace-Präfix, Zwischen-Namespaces und dem Klassennamen. Schauen wir uns ein Beispiel an. Angenommen, du definierst diese Zuordnung: Der Präfix App\ ist an das Verzeichnis src/ gebunden. Dann gilt:

  • Klasse App\Mailersrc/Mailer.php
  • Klasse App\Services\Invoicesrc/Services/Invoice.php
  • App\Http\Controllers\HomeControllersrc/Http/Controllers/HomeController.php

Die Mechanik ist einfach: Der Namespace-Präfix (hier App\) wird durch das Basisverzeichnis (src/) ersetzt; jeder verbleibende Namespace-Trenner (\) wird zu einem Verzeichnistrenner (/); und am Ende kommt .php hinzu. Drei Punkte verdienen Beachtung:

  • Die Zuordnung ist case-sensitiv. Die Datei für App\Mailer muss Mailer.php heißen, nicht mailer.php. Das ist vor allem auf Linux-Servern entscheidend; macOS/Windows verzeihen es lokal, in der Produktion bricht es.
  • Der Dateiname muss exakt mit dem darin enthaltenen Klassennamen übereinstimmen.
  • Der Präfix muss einem Basisverzeichnis entsprechen; der Präfix selbst ist kein Ordnername, er bildet direkt auf diesen Ordner ab.

PSR-4 mit composer.json konfigurieren

In der Praxis schreibst du deinen eigenen Autoloader nicht von Hand; du verwendest den, den Composer generiert. Du musst lediglich deine PSR-4-Zuordnung im Abschnitt autoload der composer.json hinzufügen:

{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

Beachte, dass der Backslash im JSON maskiert wird (App\\). Du kannst auch mehrere Präfixe definieren; das Trennen von Anwendungscode und Testcode ist üblich:

{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    }
}

Hier greift autoload-dev nur in der Entwicklung; bei der Installation für die Produktion mit composer install --no-dev wird der Test-Namespace nicht geladen. Nach dem Hinzufügen oder Ändern einer Zuordnung musst du die Autoload-Map neu generieren:

composer dump-autoload

Dieser Befehl aktualisiert die Maps unter vendor/composer/. Du musst ihn nur ausführen, wenn du einen neuen PSR-4-Präfix hinzufügst oder die Namespace-Struktur änderst; eine neue Klasse zu einem bestehenden Namespace hinzuzufügen erfordert keinen Dump, da PSR-4 die Datei aus dem Pfad ableitet.

Verwendung: ein einzeiliger Einstiegspunkt

Sobald die Zuordnung steht, musst du im Einstiegspunkt deines Projekts (zum Beispiel public/index.php) nur den von Composer generierten Autoloader einbinden:

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

use App\Services\Invoice;
use App\Mailer;

$invoice = new Invoice();
$mailer  = new Mailer();

Jetzt laden sowohl deine eigenen Klassen als auch alle installierten Pakete, sobald ihr Name referenziert wird. Die Klassendatei selbst muss mit einer Namespace-Deklaration beginnen; src/Services/Invoice.php sieht zum Beispiel so aus:

<?php

namespace App\Services;

class Invoice
{
    public function total(): float
    {
        return 0.0;
    }
}

Die Zeile namespace App\Services; muss vollständig mit der Position der Datei in der PSR-4-Zuordnung übereinstimmen. Eine Abweichung ist die häufigste Ursache des Fehlers „Class not found".

Der Unterschied zwischen psr-4, classmap und files

Composer unterstützt drei verschiedene Autoload-Strategien, und zu wissen, wann man welche nutzt, macht das Leben leichter:

  • psr-4: Bildet einen Namespace auf ein Verzeichnis ab und leitet die Datei aus dem Pfad ab. Die Standardwahl für modernen Code; eine neue Klasse hinzuzufügen erfordert keinen Dump.
  • classmap: Durchsucht die angegebenen Ordner und schreibt den direkten Dateipfad jeder Klasse in eine Map. Praktisch für Legacy-Code, der die Namespace-Konvention nicht befolgt, erfordert aber dump-autoload bei jeder neu hinzugefügten Klasse.
  • files: Lädt bei jeder Anfrage bedingungslos Dateien mit Funktionsdefinitionen (keine Klassen). Wird typischerweise für globale Hilfsfunktionen (Helper) verwendet.

Für die meisten Projekte genügt psr-4 allein. classmap und files kommen vor allem bei der Integration älterer, namespace-loser Bibliotheken ins Spiel.

Autoload-Optimierung in der Produktion

PSR-4 ist flexibel, aber diese Flexibilität hat einen kleinen Preis: Zur Laufzeit berechnet PHP den Dateipfad aus dem Klassennamen und prüft, ob die Datei auf der Festplatte existiert. In der Produktion kannst du das beschleunigen, indem du es vorberechnest:

composer dump-autoload --optimize

Dieser Befehl (Kurzform -o) durchsucht alle PSR-4-Klassen und wandelt sie in eine Classmap um, wodurch Dateisuchen zur Laufzeit entfallen. Im Deploy-Schritt verwendest du üblicherweise diese Kombination:

composer install --no-dev --optimize-autoloader

Ein Vorbehalt: Eine optimierte Classmap ist statisch. Wenn du in der Produktion eine neue Klassendatei hinzufügst, wird die neue Klasse erst gefunden, wenn du den Dump erneut ausführst. Deshalb ist das Optimize-Flag für das Deployment gedacht, nicht für die Entwicklungsumgebung.

Häufige Fragen

Ich bekomme einen „Class not found"-Fehler, wo soll ich nachsehen?

Prüfe zuerst drei Dinge: Ist die namespace-Deklaration in der Datei mit der PSR-4-Zuordnung konsistent, ist der Dateiname exakt gleich dem Klassennamen einschließlich Groß-/Kleinschreibung, und stimmt das Basisverzeichnis in der composer.json. Wenn du einen neuen Präfix hinzugefügt hast, vergiss nicht, composer dump-autoload auszuführen. Erscheint der Fehler nur in der Produktion, ist es fast immer ein Groß-/Kleinschreibungs-Unterschied; das Linux-Dateisystem ist case-sensitiv.

Was ist der Unterschied zwischen PSR-4 und PSR-0?

PSR-0 ist der ältere Standard und strenger: Es interpretiert Unterstriche (_) im Namespace als Verzeichnistrenner und spiegelt den gesamten Präfix in der Verzeichnisstruktur wider. PSR-4 bildet den Präfix dagegen direkt auf ein Basisverzeichnis ab, sodass du flachere, sauberere Ordnerstrukturen aufbauen kannst. PSR-0 ist inzwischen veraltet (deprecated); bevorzuge in neuen Projekten immer PSR-4.

Muss ich für jede neue Klasse dump-autoload ausführen?

Nein. Da PSR-4 die Datei aus dem Namespace ableitet, erfordert das Hinzufügen einer neuen Klasse zu einer bestehenden Zuordnung keinen zusätzlichen Befehl; die Klasse funktioniert sofort. dump-autoload ist nur nötig, wenn du einen neuen PSR-4-Präfix hinzufügst, eine Classmap verwendest oder für die Produktion optimierst.

Ist die Autoload-Einrichtung in deinem PHP-Projekt durcheinandergeraten? Wenn du Hilfe bei der Namespace-Organisation, „class not found"-Fehlern, der Migration von Legacy-Code zu PSR-4 oder der sauberen Architektur eines Laravel/Symfony-basierten Projekts brauchst, nimm Kontakt mit mir auf — bringen wir deine Codebasis gemeinsam auf ein solides Fundament.

Bu kategorideki tüm yazılar →

Devamı için