Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 Push Meldungen
 Kontakt
 Script Installation
 Php
 Php Tutorials
 Lernpfade
 Webhoster Vergleich
 Impressum

Community-Bereich
 kostenlos Registrieren
 Anmelden
 Benutzerliste

Script Datenbank
 Script Archiv
 Script Top 20
 Screenshots
 Testberichte

Suche
 

Unsere Php Scripts
 Counter Script
 Umfrage Script
 Bilder Upload Script
 Terminverwaltung
 Simple PHP Forum
 RSS Grabber

Tools und Generatoren
 .htpasswd Generator
 md5 Generator
 base64 Generator
 Markdown to HTML
 Colorpicker
 Unix timestamp Tool
 Unit Test Generator
 TLD Liste
 Webkatalog‑Verzeichnis

Webspace-Mieten.d...
Webhosting mit Plesk aus Erfurt: Vier...
https://www.Webspace-Mieten.de
Hosterplus.de
Bekommen Sie Speicherplatz (Webspace), Domains...
https://www.Hosterplus.de
 
 
 

PHP class_alias() Function: Klassen umbenennen ohne Bruch

Sie befinden sich: Home > Php Tutorial > PHP class_alias() Function:...

PHP class_alias() Function: Klassen umbenennen ohne Bruch
Veröffentlicht am:
09.11.2026
Hits / Besucher:
3
Sprache:
  Deutsch
Tutorial Art:
eigenes
Eingetragen von:
Merkliste:
 
Beschreibung

Eine Shop-Bibliothek zieht um: Aus der Klasse Shop_Warenkorb wird Shop\Neu\Warenkorb. Im eigenen Code ist das schnell ersetzt, aber Plugins von Dritten, alte Templates und gespeicherte Sessions kennen nur den alten Namen. Wie man mit use … as innerhalb einer Datei einen kürzeren Namen vergibt, zeigt das Tutorial zu PHP Namespaces. PHP class_alias() geht weiter: Es legt zur Laufzeit einen zweiten, überall gültigen Namen für dieselbe Klasse an. Genau das braucht alter Code, der nach dem Umzug weiterlaufen soll.

Illustration zum Tutorial: PHP class_alias() Function: Klassen umbenennen ohne Bruch

Alle Beispiele liefen unter Windows und Linux mit PHP 8.4, Versionsunterschiede wurden zusätzlich mit PHP 8.2, 8.3 und 8.5 geprüft.

Was PHP class_alias() macht

PHP class_alias() erzeugt keine neue Klasse und keine Kopie. Die Funktion trägt einen weiteren Namen in die Klassentabelle ein, der auf die vorhandene Klasse zeigt:

<?php

class Versand
{
public static int $zaehler = 0;
}
var_dump(class_alias('Versand', 'Mailer'));
/* bool(true) */

$m = new Mailer();
echo get_class($m), "\n";
/* Versand */
Mailer::$zaehler = 5;
echo Versand::$zaehler;
/* 5 */

Das Objekt gehört zur Klasse Versand, auch wenn es über den Alias entstanden ist. Statische Properties teilen sich beide Namen, weil es nur eine Klasse gibt.

Syntax und Parameter im Original

Drei Parameter, der dritte ist optional:

class_alias(

string $class,
string $alias,
bool $autoload = true
): bool

/* class_alias() is used to create an alias for a
class at runtime.
class - the name of the original class
alias - the alias name for the class
autoload - whether to autoload the original
class if it is not found
return - true on success, false on failure
(with a PHP Warning).
The aliased class can be used under both names;
objects created via the alias are instances of
the original class. Aliases work for classes,
interfaces, traits and enums. Since PHP 8.3 an
alias of an internal class can be created, too.
The alias is global, not in the same namespace
as the calling code. */

Der Alias gilt global und ab dem Moment des Aufrufs bis zum Ende der Anfrage. Entfernen lässt er sich nicht, PHP bietet dafür keine Funktion. Der dritte Parameter steuert, ob PHP für die Originalklasse den Autoloader fragt.

Alias und Originalklasse: get_class(), instanceof und ::class

Liegt die Originalklasse in einem Namespace, taucht fast überall der volle Originalname auf:

<?php

namespace App\Mail;

class Versand
{
public function wer(): string
{
return static::class;
}
}
class_alias(Versand::class, 'Mailer');

$m = new \Mailer();
echo get_class($m), "\n";
/* App\Mail\Versand */
echo $m->wer(), "\n";
/* App\Mail\Versand */
echo \Mailer::class, "\n";
/* Mailer */
var_dump($m instanceof \Mailer);
/* bool(true) */
$r = new \ReflectionClass('Mailer');
echo $r->getName();
/* App\Mail\Versand */

Am Objekt bleibt der Alias nur an einer Stelle sichtbar: Mailer::class. Dieser Ausdruck wird schon beim Kompilieren durch den geschriebenen Namen ersetzt, PHP schaut dafür nicht einmal in die Klassentabelle. $m::class liefert dagegen den Originalnamen, ebenso self::class, var_dump() und serialize(). Steht der Alias aber als Typ in einer Signatur, nennen Reflection und Fehlermeldungen den geschriebenen Namen. In get_declared_classes() fehlt der Alias; was die Funktion sonst liefert, zeigt das Tutorial zu get_declared_classes(). Wer wissen will, ob ein Name ein Alias ist, vergleicht ihn ohne Rücksicht auf Groß- und Kleinschreibung mit (new ReflectionClass($name))->getName(), denn auch für app\mail\versand liefert Reflection App\Mail\Versand.

Das Beispiel zeigt nebenbei eine Falle: Obwohl class_alias() im Namespace App\Mail aufgerufen wird, entsteht der globale Name Mailer, nicht App\Mail\Mailer. Der zweite Parameter ist ein String und wird nicht relativ zum Namespace aufgelöst. Wer den Alias im Namespace haben will, schreibt __NAMESPACE__ . '\Mailer'.

class_alias() oder use … as?

Beide vergeben einen anderen Namen, aber auf völlig verschiedenen Ebenen:

<?php

namespace Shop\Neu {
class Warenkorb {}
}

namespace Bestellung {
use Shop\Neu\Warenkorb as Korb;

echo Korb::class, "\n";
/* Shop\Neu\Warenkorb */
var_dump(class_exists('Korb'));
/* bool(false) */

class_alias(Korb::class, 'AlterKorb');
var_dump(class_exists('AlterKorb'));
/* bool(true) */
}

use … as ist eine Schreibhilfe für genau eine Datei. PHP ersetzt Korb beim Kompilieren durch den vollen Namen, zur Laufzeit gibt es keine Klasse Korb, und ein new $name mit dem String 'Korb' scheitert mit Class "Korb" not found. Der Name aus PHP class_alias() existiert dagegen wirklich: in jeder Datei, für Strings, für unserialize() und für fremden Code. Wer nur einen langen Klassennamen abkürzen will, nimmt use … as. Wer alten Code mit einer umbenannten Klasse versorgen muss, braucht den Alias.

Der Parameter autoload

Ist die Originalklasse beim Aufruf noch nicht geladen, fragt PHP class_alias() standardmäßig den Autoloader nach ihr. Wie Autoloader arbeiten, beschreibt das Tutorial zum Autoloading mit PSR-4:

<?php

spl_autoload_register(function (string $klasse) {
echo "Autoloader: $klasse\n";
$datei = __DIR__ . '/Artikel.php';
if ($klasse === 'Lager\Artikel') {
require $datei;
}
});

var_dump(@class_alias('Lager\Artikel', 'A1', false));
/* bool(false), der Autoloader wird nicht gefragt */

var_dump(class_alias('Lager\Artikel', 'A2'));
/* Autoloader: Lager\Artikel
bool(true) */

Die Datei Artikel.php enthält nur die Klasse:

<?php

/* Datei: Artikel.php */
namespace Lager;

class Artikel {}

Ohne das @ erscheint bei false die Warnung Class "Lager\Artikel" not found. Den Alias-Namen selbst lädt PHP nie nach.

Klassen umbenennen ohne Bruch mit PHP class_alias()

Wie man das sauber macht, zeigt eine Bibliothek, die in vielen Projekten im vendor-Ordner liegt. Der PHP-Parser von Nikita Popov hat in Version 5 etliche Klassen umbenannt, etwa Scalar\LNumber in Scalar\Int_. Am Ende der neuen Klassendatei steht dort ein Aufruf von PHP class_alias() mit dem Kommentar „@deprecated compatibility alias“. Unter dem alten Dateinamen liegt eine kleine Datei, die nur die neue einbindet. Übertragen auf eigenen Code:

<?php

/* Datei: src/Mail/Versand.php */
namespace App\Mail;

class Versand
{
}

/* @deprecated alter Name, entfällt in 3.0 */
class_alias(Versand::class, 'Mail_Versand');

Unter dem alten Pfad bleibt nur diese Datei:

<?php

/* Datei: Mail/Versand.php */
require __DIR__ . '/../src/Mail/Versand.php';

if (false) {
class Mail_Versand extends \App\Mail\Versand
{
}
}

Der Block mit if (false) wird nie ausgeführt. Er ist für Werkzeuge da, die Klassen durch Lesen statt Ausführen finden, etwa den Classmap-Generator von Composer, IDEs und statische Analyse. Fragt alter Code nach Mail_Versand, lädt der Autoloader die alte Datei, und die bindet die neue samt Alias ein:

<?php

require __DIR__ . '/Mail/Versand.php';

$v = new Mail_Versand();
echo get_class($v);
/* App\Mail\Versand */

Verlockend ist eine Abkürzung: den Alias erst im Autoloader anlegen, sobald jemand nach dem alten Namen fragt. Das hat einen Haken, den der Test deutlich zeigte. instanceof, Typdeklarationen und catch fragen keinen Autoloader. Solange niemand den alten Namen per new oder statischem Aufruf angefasst hat, gilt er als unbekannt:

flowchart TD
    A[Alter Name im Code] --> B{Alias angelegt?}
    B -- ja --> C[Originalklasse wird benutzt]
    B -- nein --> D{new, statisch, unserialize?}
    D -- ja --> E[Autoloader legt Alias an]
    E --> C
    D -- nein --> F[instanceof und Typen: false]

Im Code sieht die Falle so aus:

<?php

namespace Shop {
class Bon {}
}
namespace {
spl_autoload_register(function (string $k) {
if ($k === 'Alter_Bon') {
class_alias('Shop\Bon', 'Alter_Bon');
}
});
function drucke(Alter_Bon $bon): string
{
return 'gedruckt';
}
$bon = new Shop\Bon();
var_dump($bon instanceof Alter_Bon);
/* bool(false) */
try {
drucke($bon);
} catch (TypeError $e) {
echo strtok($e->getMessage(), ','), "\n";
}
/* drucke(): Argument #1 ($bon) must be of type
Alter_Bon */
class_exists('Alter_Bon');
echo drucke($bon);
/* gedruckt */
}

Erst nachdem class_exists() den Autoloader ausgelöst hat, stimmt alles. Der Alias gehört deshalb an das Ende der neuen Klassendatei. Der Autoloader-Weg taugt nur zusätzlich, etwa um mit trigger_error() und E_USER_DEPRECATED auf den alten Namen hinzuweisen. Im Test kam diese Meldung genau einmal, beim ersten new, und nur solange die neue Klasse noch nicht geladen war. Danach existiert der Alias schon, und der Autoloader wird für den alten Namen nicht mehr gefragt.

Ein Gewinn zeigt sich bei serialisierten Daten. unserialize() fragt den Autoloader sehr wohl, und mit Alias entsteht aus dem alten Namen ein Objekt der neuen Klasse:

<?php

namespace Shop\Neu {
class Warenkorb
{
public array $posten = [];
}
}
namespace {
$alt = 'O:9:"Shop_Korb":1:{s:6:"posten";'
. 'a:1:{i:0;s:5:"Tasse";}}';
echo get_class(unserialize($alt)), "\n";
/* __PHP_Incomplete_Class */

class_alias('Shop\Neu\Warenkorb', 'Shop_Korb');
$korb = unserialize($alt);
echo get_class($korb), ' ', $korb->posten[0];
/* Shop\Neu\Warenkorb Tasse */
}

Beim nächsten serialize() steht dann der neue Name in der Session. Gespeicherte Warenkörbe wandern so beim normalen Betrieb auf die neue Klasse.

Alias oder leere Unterklasse?

Statt PHP class_alias() liest man in älterem Code oft class Alt extends Neu {}. Die beiden Varianten verhielten sich im Test sehr unterschiedlich:

Prüfung class_alias() leere Unterklasse
get_class(new Alt()) Neu Alt
new Neu() instanceof Alt true false
Funktion mit Typ Alt bekommt new Neu() funktioniert TypeError
serialize(new Alt()) neuer Name alter Name bleibt
Originalklasse ist final funktioniert Fatal error

Die Unterklasse ist ein neuer Typ, der Alias derselbe. Alter Code, der Objekte der neuen Klasse unter dem alten Typ erwartet, bricht nur mit der Unterklasse. Bei einer finalen Klasse meldet PHP sogar Class S cannot extend final class E, während der Alias klaglos entsteht.

Interfaces, Traits, Enums und interne Klassen

PHP class_alias() funktioniert nicht nur mit Klassen. Interfaces, Traits und Enums lassen sich genauso aliasen, und bei Exceptions fängt ein catch mit dem alten Namen auch die neue Klasse:

<?php

class ZahlungFehlgeschlagen extends RuntimeException {}
class_alias('ZahlungFehlgeschlagen', 'Zahlung_Fehler');

try {
throw new ZahlungFehlgeschlagen('Karte abgelehnt');
} catch (Zahlung_Fehler $e) {
echo get_class($e), "\n";
}
/* ZahlungFehlgeschlagen */

enum Status: string
{
case Offen = 'o';
case Bezahlt = 'b';
}
class_alias(Status::class, 'Bestellstatus');
echo Bestellstatus::from('b')->name;
/* Bezahlt */

Ein Interface-Alias erfüllt das Original: Eine Klasse mit implements AltesInterface besteht die Prüfung auf das neue Interface. interface_exists() erkennt den Alias, class_exists() nicht. Bei eingebauten Klassen entscheidet die PHP-Version:

<?php

class_alias('DateTimeImmutable', 'Zeitpunkt');
$z = new Zeitpunkt('2026-11-02');
echo get_class($z), ' ', $z->format('d.m.Y');
/* DateTimeImmutable 02.11.2026 */

Ab PHP 8.3 klappt das. PHP 8.2 brach im Test mit ValueError: class_alias(): Argument #1 ($class) must be a user-defined class name, internal class name given ab. Wer 8.2 noch unterstützt, prüft vorher PHP_VERSION_ID >= 80300. Statische Analyse wie PHPStan führt den geprüften Code nicht aus. Einen Laufzeit-Alias kennt PHPStan nur, wenn die Datei mit dem Aufruf unter bootstrapFiles eingetragen ist, denn diese Dateien führt es tatsächlich aus. Bloßes Mitlesen über scanFiles genügte im Test nicht, PHPStan meldete weiter class.notFound. Ohne diesen Eintrag helfen die if (false)-Blöcke aus dem Umbenennungsmuster, denn die Klasse darin findet PHPStan schon durch Lesen.

Fehlermeldungen bei PHP class_alias()

Ist der gewünschte Name schon belegt oder fehlt die Originalklasse, gibt es eine Warnung und false:

<?php

class Original {}
class Belegt {}

var_dump(class_alias('Original', 'Belegt'));
/* Warning: Cannot redeclare class Belegt
(previously declared in ...)
bool(false) */

var_dump(class_alias('GibtEsNicht', 'Egal'));
/* Warning: Class "GibtEsNicht" not found
bool(false) */

Die erste Meldung hat zwei Tücken. Seit PHP 8.4 lautet sie Cannot redeclare class Belegt (previously declared in …), in PHP 8.2 und 8.3 noch Cannot declare class Belegt, because the name is already in use. Und die Ortsangabe zeigt nicht auf die Klasse, die den Namen belegt, sondern auf die Originalklasse, die einen Alias bekommen sollte. Wer der Zeilennummer folgt, sucht an der falschen Stelle.

Härter trifft es reservierte Namen. class_alias('Original', 'int') endete mit Fatal error: Cannot use "int" as a class alias as it is reserved, und das Skript brach ab. Dasselbe galt für string, bool, self, static, void, mixed und weitere Typnamen. Sonst prüft PHP den Namen kaum: Ein Alias mit Leerzeichen oder ein leerer String wurde angelegt, ein führender Backslash einfach entfernt.

Fazit

PHP class_alias() gibt einer Klasse einen zweiten Namen, keinen zweiten Typ. Objekte, Reflection, serialize() und statische Properties gehören weiter zur Originalklasse, am Objekt liefert nur Alt::class den Alias-String. Für Abkürzungen innerhalb einer Datei ist use … as das bessere Werkzeug, für umbenannte oder verschobene Klassen der Alias.

Beim Umbenennen gehört der Aufruf von PHP class_alias() an das Ende der neuen Klassendatei, ergänzt um eine kleine Datei unter dem alten Namen. Ein Alias, der erst im Autoloader entsteht, lässt instanceof und Typprüfungen scheitern, bis der alte Name einmal geladen wurde. Interne Klassen lassen sich erst ab PHP 8.3 aliasen, und reservierte Typnamen beenden das Skript sofort.

 

Tags:

 

 

Kommentare (0)

Noch keine Kommentare. Sei der Erste!

Melde dich an, um einen Kommentar zu schreiben.
Bücherregal mit drei Büchern: 'PHP 4 - Grundlagen und Profiwissen' von Hanser Verlag, 'Webdesign in a Nutshell' von O'Reilly Verlag, und 'Webgestaltung' von Galileo Computing.