# Namespaces und Autoloading (PSR-4)

> PHP-Namespaces und Autoloading mit PSR-4: vom Klassennamen zum Dateipfad, spl_autoload_register, Composer-Autoloader und Prüfung nach Vorfällen.

Quelle: https://phpsos.de/php/namespaces-autoloading/  
Stand: 25.10.2026  
Anbieter: PHP SOS, PHP-Notfallhilfe und Server-Sicherheit. Soforthilfe per WhatsApp: https://wa.me/491736494914?text=Hallo%20PHP%20SOS%2C%20wir%20brauchen%20Hilfe%20mit%20unserem%20PHP-Server.%20Firma%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**Kurz gesagt:** Namespaces sind in PHP so etwas wie Ordner für Klassennamen: `App\Rechnung\Pdf` und `Bibliothek\Pdf` können nebeneinander existieren, ohne sich zu stören. Autoloading sorgt dafür, dass PHP eine Klasse erst dann lädt, wenn sie zum ersten Mal gebraucht wird. Der Standard PSR-4 legt fest, wie aus einem Klassennamen ein Dateipfad wird; Composer erzeugt danach den passenden Autoloader. Weil dieser Autoloader bei jeder Anfrage läuft, gehört er nach einem Sicherheitsvorfall zu den ersten Dingen, die geprüft werden.

## Warum PHP Namespaces braucht

Namespaces gibt es seit PHP 5.3.0. Vorher teilten sich alle Klassen und Funktionen einen einzigen globalen Namensraum. Hießen zwei Bibliotheken `Logger`, krachte es. Entwickler halfen sich mit langen Namen wie `Firma_Modul_Unterbereich_Logger`.

Das PHP-Handbuch nennt zwei Probleme, die Namespaces lösen: Namenskollisionen zwischen eigenem Code, PHP-internen Klassen und Bibliotheken von Drittanbietern, sowie überlange Namen, die nur zur Umgehung dieser Kollisionen entstanden sind. Für Entscheider bedeutet das: Erst Namespaces haben es praktikabel gemacht, Dutzende fremde Pakete in einem Projekt zu kombinieren, wie es mit [Composer](https://phpsos.de/php/composer/) heute üblich ist.

## Namespaces in der Praxis: namespace, use, Aliase

Eine Datei deklariert ihren Namespace in der ersten Anweisung. Mit `use` holt man Klassen aus anderen Namespaces herein, auf Wunsch unter einem kürzeren Namen.

```php
<?php
declare(strict_types=1);

namespace App\Rechnung;

use App\Kunde\Kunde;
use Psr\Log\LoggerInterface as Log;

final class PdfErzeuger
{
    public function __construct(private Log $log) {}

    public function erzeugen(Kunde $kunde): string
    {
        $this->log->info('PDF erzeugt', ['kunde' => $kunde->id]);
        return \sprintf('Rechnung für %s', $kunde->name);
    }
}
```

Der vollständige Name dieser Klasse lautet `App\Rechnung\PdfErzeuger`. Der führende Backslash bei `\sprintf` verweist ausdrücklich auf die globale PHP-Funktion.

## Autoloading: Klassen bei Bedarf laden

Ohne Autoloading müsste jedes Skript alle benötigten Dateien mit `require` einbinden. Mit `spl_autoload_register()` registriert man stattdessen eine Funktion, die PHP aufruft, sobald eine unbekannte Klasse, ein Interface, ein Trait oder ein Enum verwendet wird. Sie bekommt den Klassennamen und lädt die passende Datei.

```php
<?php
spl_autoload_register(function (string $klasse): void {
    $praefix = 'App\\';
    $basis   = __DIR__ . '/src/';

    if (!str_starts_with($klasse, $praefix)) {
        return; // nicht zuständig, nächster Autoloader ist dran
    }
    $datei = $basis . str_replace('\\', '/', substr($klasse, strlen($praefix))) . '.php';
    if (is_file($datei)) {
        require $datei;
    }
});
```

`spl_autoload_register()` lässt sich mehrfach aufrufen. PHP fragt die registrierten Autoloader dann nacheinander, bis einer die Klasse geladen hat. In der Praxis haben große Anwendungen oft mehrere davon: den Composer-Autoloader für Bibliotheken, einen eigenen des CMS und weitere von Plugins oder Modulen. Für Admins bedeutet das: Welcher Code bei einer Anfrage tatsächlich geladen wird, ergibt sich aus dem Zusammenspiel aller dieser Autoloader und nicht allein aus der Ordnerstruktur.

Das Handbuch rät dringend davon ab, in einem Autoloader Exceptions zu werfen; PSR-4 verbietet es ausdrücklich. Die ältere Funktion `__autoload()` wurde mit PHP 7.2.0 als veraltet markiert und mit PHP 8.0.0 entfernt.

## PSR-4: vom Klassennamen zum Dateipfad

PSR-4 ist ein Standard der PHP-FIG. Ein vollständiger Klassenname beginnt mit einem Hersteller-Namespace. Ein Präfix des Namespace wird einem Basisverzeichnis zugeordnet, der Rest des Namens ergibt Unterordner, und die Datei endet auf `.php`. Groß- und Kleinschreibung muss genau übereinstimmen. So sieht die Zuordnung in der `composer.json` aus:

```json
{
    "autoload": {
        "psr-4": { "App\\": "src/" }
    }
}
```

| Klassenname | Datei |
|---|---|
| `App\Kunde\Kunde` | `src/Kunde/Kunde.php` |
| `App\Rechnung\PdfErzeuger` | `src/Rechnung/PdfErzeuger.php` |
| `App\Rechnung\Pdf\Vorlage` | `src/Rechnung/Pdf/Vorlage.php` |

Ein klassischer Stolperstein ist die Groß- und Kleinschreibung. Auf Entwicklungsrechnern mit Windows oder macOS unterscheidet das Dateisystem oft nicht zwischen `Kunde.php` und `kunde.php`, auf einem Linux-Server schon. Eine Anwendung, die lokal läuft, findet dann auf dem Server eine Klasse nicht. Die Regel aus PSR-4, Namen exakt in der richtigen Schreibweise zu verwenden, verhindert solche Überraschungen bei der Auslieferung.

Neben `psr-4` kennt Composer `classmap` für Code ohne Standardstruktur und `files` für Dateien, die bei jeder Anfrage geladen werden, etwa Hilfsfunktionen. Weitere Standards der PHP-FIG beschreibt die Seite [PSR-Standards](https://phpsos.de/php/psr-standards/).

## Autoloader in der Produktion optimieren

In der Produktion sucht der Autoloader am besten nicht mehr im Dateisystem, sondern schlägt in einer fertigen Liste nach. Composer bietet dafür zwei Stufen:

1. `composer install --no-dev --optimize-autoloader` wandelt die PSR-4-Regeln in eine Klassenliste um. Das ist laut Composer-Dokumentation für die Produktion empfohlen.
2. `--classmap-authoritative` geht weiter: Klassen werden ausschließlich aus der Liste geladen. Nicht aufgeführte Dateien lädt der Autoloader dann gar nicht.
3. Bei jeder Auslieferung wird die Liste neu erzeugt, damit neue Klassen gefunden werden.

## Autoloading und Sicherheit nach PHP2Shell

PHP2Shell betrifft den PHP-Interpreter, nicht den Autoloader. Pflicht bleiben das Update auf PHP 8.5.12, 8.4.27, 8.3.36 oder 8.2.35 und der Neustart aller Worker. Nach einem möglichen Vorfall verdient der Autoloader aber besondere Aufmerksamkeit: `vendor/autoload.php` und alle unter `files` eingetragenen Dateien werden bei jeder Anfrage ausgeführt. Eine dort eingeschleuste Zeile wirkt also auf der ganzen Website, ohne dass eine auffällige neue Datei im Upload-Ordner liegt.

Prüfen Sie deshalb, ob `vendor` und die Autoload-Dateien zum geprüften Stand aus der Versionsverwaltung passen. Hilfreich sind die Beiträge [Kürzlich geänderte Dateien finden](https://phpsos.de/blog/geaenderte-dateien-finden/) und [CMS-Kerndateien mit dem Original vergleichen](https://phpsos.de/blog/cms-kerndateien-vergleichen/). Im Zweifel ist ein frisch erzeugtes `vendor` aus der Lock-Datei sicherer als jede Einzelreparatur.

## Wie hilft PHP SOS konkret?

- Wir vergleichen `vendor`, Autoloader und Einstiegsdateien mit dem geprüften Stand und markieren jede Abweichung.
- Wir stellen den Paketbestand aus der Lock-Datei neu her und richten einen optimierten Autoloader ein.
- Wir prüfen, ob nur der öffentliche Ordner im Webroot liegt und Quellcode nicht direkt per URL erreichbar ist.
- Bei Befall übernehmen wir die Bereinigung im Rahmen der [Malware-Entfernung](https://phpsos.de/leistungen/malware-entfernung/) und dokumentieren das Ergebnis.


## Häufige Fragen

**Seit wann gibt es Namespaces in PHP?**  
Seit PHP 5.3.0. Sie lösen laut Handbuch zwei Probleme: Namenskollisionen zwischen eigenem Code, PHP und Bibliotheken von Drittanbietern sowie überlange Klassennamen, die nur entstanden, um solche Kollisionen zu vermeiden.

**Was ist der Unterschied zwischen PSR-0 und PSR-4?**  
Beide bilden Klassennamen auf Dateipfade ab. Bei PSR-4 wird das Namespace-Präfix nicht im Dateipfad wiederholt, was flachere Verzeichnisse ergibt. PSR-0 ist bei der PHP-FIG als veraltet eingestuft, PSR-4 ist der empfohlene Standard.

**Funktioniert __autoload() noch?**  
Nein. __autoload() wurde mit PHP 7.2.0 als veraltet markiert und mit PHP 8.0.0 entfernt. Heute registriert man Autoloader mit spl_autoload_register(), in der Praxis meist über den von Composer erzeugten Autoloader.

**Muss ich nach dem Anlegen einer neuen Klasse den Autoloader neu erzeugen?**  
Bei reinen PSR-4-Regeln nicht, laut Composer-Dokumentation ist das gerade ein Vorteil von PSR-4. Wer in der Produktion eine optimierte Klassenliste nutzt, muss sie bei jeder Auslieferung neu erzeugen.

## Quellen

- [PHP-FIG: PSR-4 Autoloader](https://www.php-fig.org/psr/psr-4/)
- [PHP-Handbuch: Namespaces, Überblick](https://www.php.net/manual/de/language.namespaces.rationale.php)
- [PHP-Handbuch: Autoloading](https://www.php.net/manual/de/language.oop5.autoload.php)
- [Composer: The composer.json schema](https://getcomposer.org/doc/04-schema.md)
