Menu

PHP Namespace: namespace, use und Aliase

Ein PHP-Namespace gruppiert Klassen, Funktionen und Konstanten unter einem Präfix: namespace App\Models; am Anfang einer Datei und dann use App\Models\User; an anderer Stelle, um die Klasse mit ihrem kurzen Namen anzusprechen. Hier: vollqualifizierte Namen, Aliase mit use ... as, use function, der führende Backslash für globale Klassen und Autoloading nach PSR-4.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

Ein PHP-Namespace stellt Klassen, Funktionen und Konstanten unter ein Präfix, damit ihre Namen nicht mit denen anderer kollidieren. Du deklarierst ihn mit namespace App\Models; als erste Anweisung einer Datei, und andere Dateien sprechen die Klasse als \App\Models\User an oder importieren sie mit use App\Models\User; und schreiben nur User.

Im Namespace bedeutet User dasselbe wie App\Models\User. User::class liefert den vollen Namen als String, ohne etwas zu erzeugen, praktisch für Logging und für Autoloader.

Zwei Namespaces in einer Datei

Ein echtes Projekt legt einen Namespace pro Datei an. Für eine in sich geschlossene Demo darf eine Datei mehrere Namespaces enthalten, wenn jeder in geschweifte Klammern gesetzt ist. Code, der zu keinem Namespace gehört, kommt in namespace { }:

Zwei Klassen namens Order leben nebeneinander, weil sich ihre vollen Namen unterscheiden. Genau dieses Problem lösen Namespaces, sobald du Bibliotheken installierst: Dein Order, das Order einer Zahlungsbibliothek und das Order einer PDF-Bibliothek kollidieren nicht mehr.

Mit use importieren und mit as einen Alias vergeben

Überall \Shop\Order zu schreiben ist unübersichtlich. use am Anfang einer Datei (oder eines Namespace-Blocks) importiert einen Namen, sodass du die kurze Form verwenden kannst. Wenn zwei Importe auf denselben kurzen Namen enden würden, gibt as einem davon einen anderen Namen:

use erzeugt nur einen kurzen Namen für den Rest der Datei. Es lädt keine Datei und führt keinen Code aus und funktioniert gleich, ob die Klasse schon existiert oder nicht. Gruppierte Importe sind ebenfalls erlaubt: use Shop\{Order, Invoice};.

use function und use const

Funktionen und Konstanten in einem Namespace importierst du mit use function und use const:

Globale Klassen brauchen einen Backslash

In einem Namespace wird ein nicht qualifizierter Klassenname relativ zu diesem Namespace aufgelöst, also sucht new DateTime() in namespace App; nach App\DateTime. Bei Funktionen und Konstanten ist es anders: Existiert App\strlen nicht, fällt PHP auf das globale strlen zurück. Klassen fallen nie zurück.

catch (\Error $e) brauchte aus demselben Grund einen Backslash: Ohne ihn würde PHP nach App\Error suchen, den echten Fehler nie treffen, und das Skript würde mit einem nicht abgefangenen Error stoppen. Behebe es entweder mit einem führenden Backslash, wie oben, oder mit use DateTime; am Anfang der Datei. Dasselbe gilt für \Exception, \Throwable und jede andere eingebaute Klasse; siehe try catch zum Abfangen.

Autoloading und PSR-4

In einem Projekt lebt jede Klasse in ihrer eigenen Datei, und der Dateipfad folgt dem Namespace. PSR-4 ist die Konvention: Ein Namespace-Präfix wird einem Basisordner zugeordnet, und der Rest des Namens wird zum Pfad. Ein mit spl_autoload_register() registrierter Autoloader lädt dann eine Klassendatei, sobald die Klasse zum ersten Mal verwendet wird. Dieser Block schreibt zwei Klassendateien auf die Festplatte und lädt sie automatisch:

Jede Klassendatei wird einmal geladen, in dem Moment, in dem die Klasse zum ersten Mal gebraucht wird. In echten Projekten schreibst du diese Funktion nicht selbst: Composer erzeugt sie aus ein paar Zeilen in composer.json:

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

Nach composer dump-autoload lädt ein einziges require __DIR__ . '/vendor/autoload.php'; am Anfang deines Einstiegsskripts jede App\...-Klasse bei Bedarf.

Namespace-Regeln, die Fehler verursachen

  • namespace muss die erste Anweisung der Datei sein. Nur declare(strict_types=1); und Kommentare dürfen davor stehen.
  • use-Importe gelten pro Datei. Eine Klasse in index.php zu importieren, lässt den kurzen Namen nicht in einer eingebundenen Datei funktionieren; jede Datei braucht ihre eigenen use-Zeilen.
  • use gehört auf die oberste Ebene der Datei oder des Namespace-Blocks. In einem Klassenrumpf bedeutet use etwas anderes: Es bindet einen Trait ein.
  • Strings werden nie aufgelöst: $class = 'User'; new $class(); sucht nach dem globalen User. Speichere den vollen Namen, am besten mit User::class.

Die letzte Regel verdient eine kurze Prüfung:

Häufig gestellte Fragen

Was ist ein Namespace in PHP?

Ein Präfix, das zusammengehörige Klassen, Interfaces, Funktionen und Konstanten gruppiert, wie ein Ordner für Namen. namespace App\Models; am Anfang einer Datei legt ihre Klasse User unter App\Models\User ab, sodass sie nicht mit dem User einer anderen Bibliothek kollidieren kann.

Was macht use in PHP?

use App\Models\User; am Anfang einer Datei erlaubt dir, in dieser Datei User statt des vollen Namens \App\Models\User zu schreiben. Es lädt und bindet nichts ein; die Klassendatei zu laden ist Aufgabe des Autoloaders. use ... as Alias; wählt einen anderen kurzen Namen.

Warum bekomme ich in einem Namespace Class not found?

In namespace App; wird ein bloßer Klassenname relativ zum Namespace aufgelöst, also sucht new DateTime() nach App\DateTime. Schreib new \DateTime() oder füge use DateTime; am Anfang hinzu. Funktionen und Konstanten fallen automatisch auf den globalen Namespace zurück, Klassen nicht.

Was bedeutet der Backslash vor einem Klassennamen in PHP?

Ein führender Backslash macht den Namen vollqualifiziert, ausgehend vom globalen Namespace: \Exception ist immer PHPs eingebaute Exception, egal in welchem Namespace der Code steht. Ohne ihn wird der Name relativ zum aktuellen Namespace und zu den use-Importen aufgelöst.

Wie hängen Namespaces mit Ordnern und PSR-4 zusammen?

PHP selbst verknüpft Namespaces nicht mit Ordnern. PSR-4 ist die Konvention, die das tut: Ein Präfix wie App\ wird einem Verzeichnis wie src/ zugeordnet, also liegt App\Models\User in src/Models/User.php. Der Autoloader von Composer folgt dem, und deshalb passen die beiden meist zusammen.

Illustration der Programmiersprachen bei Coddy

Lerne mit Coddy zu programmieren

LOS GEHT'S