Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 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

Artfiles.de
Bietet Serviceorientierte...
https://www.Artfiles.de
Hosterplus.de
Bekommen Sie Speicherplatz (Webspace), Domains...
https://www.Hosterplus.de
 
 
 

PHP get_called_class(): aufrufende Klasse ermitteln

Sie befinden sich: Home > Php Tutorial > PHP get_called_class(): auf...

PHP get_called_class(): aufrufende Klasse ermitteln
Eintrag am:
10.08.2026
Hits / Besucher:
4
Sprache:
  Deutsch
Tutorial Art:
eigenes
Eingetragen von:
Merkliste:
 
Beschreibung

Eine statische Methode steht in der Basisklasse, aufgerufen wird sie über eine Kindklasse, und im Protokoll landet trotzdem der Name der Basisklasse. Der Tippfehler, den man an dieser Stelle sucht, existiert nicht. PHP get_called_class() beantwortet die Frage, die der Code eigentlich stellen wollte: über welche Klasse ist diese Methode aufgerufen worden?

Illustration zum Tutorial: PHP get_called_class(): aufrufende Klasse ermitteln

Die Abbildung stellt die beiden Bindungen nebeneinander, die sich im Alltag so leicht verwechseln lassen. Wie PHP get_called_class() darauf antwortet, zeigt am schnellsten ein lauffähiges Beispiel.

Warum self:: die falsche Klasse nennt

Bei statischen Methoden verhält sich Vererbung in PHP anders, als viele es vom Umgang mit Objekten kennen. Der Bezeichner self wird beim Übersetzen aufgelöst und zeigt auf die Klasse, in der die Zeile geschrieben steht. Wer den Aufruf ausgelöst hat, bleibt dabei ohne Wirkung.

<?php

class Basis
{
public static function wer(): void
{
echo 'self: ' . self::class . "\n";
echo 'static: ' . static::class . "\n";
echo 'gcc: ' . get_called_class() . "\n";
}
}

class Kind extends Basis {}

Kind::wer();

/* Ausgabe:
self: Basis
static: Kind
gcc: Kind */

Drei Ausgaben aus derselben Methode, und nur die erste weicht ab. Der Aufruf lautete Kind::wer(), in Zeile eins steht trotzdem Basis. Beim direkten Aufruf Basis::wer() liefern alle drei denselben Namen, sichtbar wird der Unterschied also erst durch die Kindklasse. Das ist kein Mangel der Sprache, sondern ihr festgelegtes Verhalten. Die dritte Zeile zeigt bereits, was PHP get_called_class() daraus macht.

Was PHP get_called_class() zurückgibt

Die Funktion kommt ohne Argument aus und gibt eine Zeichenkette heraus: den Namen der Klasse, über die die laufende Methode angesprochen wurde. Damit ist auch die zweite häufige Erwartung geklärt. PHP get_called_class() fragt nicht nach einem Objekt, sondern nach dem Aufrufkontext, und deshalb arbeitet sie gerade dort, wo es gar kein $this gibt.

Zwei Angaben sparen später Arbeit. Erstens kommt immer der voll qualifizierte Name samt Namensraum an, aus App\Models\Benutzer wird kein bloßes Benutzer. Zweitens ist PHP get_called_class() nicht abgekündigt und arbeitet in gewachsenem Code unverändert weiter.

Late Static Binding mit static::

Der Gegenspieler zu self heißt static. Er wird erst zur Laufzeit gebunden, und zwar an die angesprochene Klasse. Diese späte Bindung trägt den Namen Late Static Binding, sie kam mit PHP 5.3, die Kurzform static::class folgte in PHP 5.5. Beides steht in jeder Version bereit, die heute noch produktiv läuft.

Sichtbar wird die späte Bindung nicht nur bei Methoden. Auch Klassenkonstanten in PHP folgen dieser Regel, und dort fällt der Unterschied im Alltag noch später auf.

<?php

class Basis
{
public const NAME = 'Basis';

public static function selbst(): string
{
return self::NAME;
}

public static function spaet(): string
{
return static::NAME;
}
}

class Kind extends Basis
{
public const NAME = 'Kind';
}

echo Kind::selbst(); /* Basis */
echo Kind::spaet(); /* Kind */

Eine Feinheit überrascht selbst erfahrene Entwickler: den aufgerufenen Klassennamen reichen nur weiterleitende Aufrufe durch. Ein static::ziel() tut das, ein ausgeschriebenes Basis::ziel() setzt den Kontext dagegen zurück. Am Ziel steht beide Male dieselbe Zeile mit PHP get_called_class(), das Ergebnis unterscheidet sich trotzdem.

<?php

class Basis
{
public static function ziel(): void
{
echo get_called_class();
}

public static function ueberStatic(): void
{
static::ziel(); /* leitet weiter */
}

public static function fest(): void
{
Basis::ziel(); /* leitet nicht weiter */
}
}

class Kind extends Basis {}

Kind::ueberStatic(); /* Kind */
Kind::fest(); /* Basis */

PHP get_called_class(), get_class() und get_class($this)

In einer Methode, die auf einem Objekt arbeitet, verschwindet der Unterschied. Dort liefern die Funktion, das Sprachkonstrukt und die Abfrage über $this denselben Namen: den der Klasse, aus der das Objekt gebaut wurde.

<?php

class P
{
public function zeig(): void
{
echo get_called_class() . ' / '
. get_class($this) . ' / '
. static::class;
}
}

class C extends P {}

(new C())->zeig(); /* C / C / C */

Der Ausgangspunkt trennt die Wege trotzdem sauber. get_class($objekt) befragt ein Objekt, PHP get_called_class() befragt den Aufruf. Ohne Objekt bleibt nur der zweite Weg, denn get_class($this) bricht in einer statischen Methode mangels $this ab.

Eine Falle steckt in der argumentlosen Variante. get_class() ohne Übergabe meint die Klasse, in der der Code steht, folgt also der Logik von self. Seit PHP 8.3 ist dieser Aufruf abgekündigt und PHP meldet Deprecated: Calling get_class() without arguments is deprecated.

static::class als moderne Schreibweise

Damit stehen fünf Schreibweisen im Raum, von denen sich einige gleich verhalten und andere eben nicht. Die Tabelle trennt sie nach statischem und nicht statischem Kontext.

Schreibweise Statischer Kontext Nicht statischer Kontext Empfehlung
self::class Klasse, in der die Zeile steht Klasse, in der die Zeile steht Nur für die eigene Klasse
static::class Aufgerufene Klasse Klasse des Objekts Erste Wahl in neuem Code
get_called_class() Aufgerufene Klasse Klasse des Objekts Arbeitet einwandfrei, in neuem Code trotzdem ersetzbar
get_class($this) Nicht verwendbar, es gibt kein $this Klasse des Objekts Passend, wenn ein konkretes Objekt vorliegt
get_class() ohne Argument Nicht verwendbar Klasse, in der die Zeile steht Seit PHP 8.3 abgekündigt, ersatzlos meiden

Bleibt die Frage nach dem Tempo. Sie lässt sich messen, und das Ergebnis ist langweilig: bei je zwei Millionen Aufrufen unter PHP 8.4 standen 0,036 Sekunden für PHP get_called_class() gegen 0,036 bis 0,038 Sekunden für das Sprachkonstrukt. Wer mit Geschwindigkeit argumentiert, hat nicht nachgemessen.

Die Empfehlung für static::class steht trotzdem, sie ruht nur auf anderen Gründen. Das Sprachkonstrukt steht direkt neben self::class, sodass der Unterschied beim Lesen auffällt. Vor allem arbeiten Werkzeuge zur statischen Analyse damit: sie leiten daraus einen Klassennamen ab, während PHP get_called_class() für sie nur eine Zeichenkette liefert.

new static() statt new self()

Jetzt zu dem Fehler, der die meisten Fehlersuchen auslöst. Eine Fabrikmethode in der Basisklasse erzeugt mit new self(), und seit dem Einbau der ersten Kindklasse kommt das falsche Objekt heraus. Wer den Namen vorher mit PHP get_called_class() ausgibt, sieht sofort, dass der Aufrufkontext stimmt und nur die Erzeugung danebengeht.

<?php

namespace App\Models;

class Model
{
public static function neu(): static
{
return new static();
}

public static function neuFalsch(): self
{
return new self();
}
}

class Benutzer extends Model {}

var_dump(get_class(Benutzer::neu()));
/* string(19) "App\Models\Benutzer" */

var_dump(get_class(Benutzer::neuFalsch()));
/* string(16) "App\Models\Model" */

Der Rückgabetyp gehört zur selben Baustelle. Ein deklariertes self bindet die Typkette an die Basisklasse, static trägt den Typ der Kindklasse weiter. Seit PHP 8.0 ist static als Rückgabetyp erlaubt, deshalb steht er in modernen Fabrikmethoden. Typabfragen mit instanceof stimmen damit wieder.

In einer abstrakten Basisklasse ist der Fehler wenigstens laut. Dort lässt sich gar kein Objekt bauen, und PHP bricht mit Error: Cannot instantiate abstract class samt dem Namen der Basisklasse ab.

Praxis: eine Basisklasse, die die richtige Kindklasse liefert

Der Anwendungsfall, wegen dem die meisten hier landen, stammt aus dem Datenbankumfeld. Jede Modellklasse soll ihren Tabellennamen aus dem eigenen Klassennamen ableiten, ohne zwanzig Konstanten in zwanzig Kindklassen. Genau dafür ist PHP get_called_class() gebaut.

<?php

namespace App\Models;

abstract class Model
{
public static function tabelle(): string
{
$klasse = get_called_class();
$pos = strrpos($klasse, '\\');
$kurz = substr($klasse, $pos + 1);

return strtolower($kurz) . 's';
}

public static function finde(int $id): static
{
$sql = 'SELECT * FROM ' . static::tabelle()
. ' WHERE id = ?';

/* Abfrage ausfuehren, Zeile holen ... */

return new static();
}
}

class Benutzer extends Model {}
class Artikel extends Model {}

echo Benutzer::tabelle(); /* benutzers */
echo Artikel::tabelle(); /* artikels */

var_dump(get_class(Benutzer::finde(1)));
/* string(19) "App\Models\Benutzer" */

Zwei Kindklassen ohne eine einzige eigene Zeile, und beide kennen ihre Tabelle. Der Aufruf static::tabelle() in finde() ist kein Zufall: self::tabelle() würde eine Kindklasse übergehen, die die Methode überschreibt. Weitere Muster zur Objekterzeugung sammelt das PHP Factory Pattern.

Eine Instanz je Kindklasse und Method Chaining

Aus derselben Idee entsteht eine Registry, die pro Kindklasse genau ein Objekt vorhält. Als Schlüssel im Array dient der Name, den PHP get_called_class() liefert. Eine gemeinsame Eigenschaft in der Basisklasse scheitert hier, weil alle Kinder sich dieselbe Ablage teilen und die zweite Klasse das Objekt der ersten bekäme.

<?php

abstract class Dienst
{
private static array $instanzen = [];

public static function hole(): static
{
$klasse = get_called_class();

if (!isset(self::$instanzen[$klasse])) {
self::$instanzen[$klasse] = new static();
}

return self::$instanzen[$klasse];
}
}

class Logger extends Dienst {}
class Cache extends Dienst {}

var_dump(get_class(Logger::hole())); /* string(6) "Logger" */
var_dump(get_class(Cache::hole())); /* string(5) "Cache" */

var_dump(Logger::hole() === Logger::hole()); /* bool(true) */
var_dump(Logger::hole() === Cache::hole()); /* bool(false) */

Die letzten beiden Zeilen belegen beides: dieselbe Kindklasse bekommt zweimal dasselbe Objekt, zwei Kindklassen bekommen verschiedene. Ob das Muster hier angebracht ist, klärt das Tutorial zum Singleton Pattern.

Der dritte Nutznießer der späten Bindung ist die verkettete Schreibweise. Ein Builder in der Basisklasse gibt $this heraus, und mit dem Rückgabetyp static bleibt der Typ der Kindklasse über die ganze Kette erhalten.

<?php

abstract class Fahrzeug
{
protected array $daten = [];

public static function erstelle(): static
{
return new static();
}

public function setze(string $k, string $v): static
{
$this->daten[$k] = $v;

return $this;
}

public function beschreibung(): string
{
return static::class . ': '
. json_encode($this->daten);
}
}

class Auto extends Fahrzeug {}

echo Auto::erstelle()
->setze('farbe', 'rot')
->beschreibung();

/* Auto: {"farbe":"rot"} */

Namensräume, Traits und anonyme Klassen

Der Rückgabewert bringt immer den vollen Pfad mit, gebraucht wird meist nur das letzte Stück. Neben dem strrpos-Weg von oben geht das mit substr(strrchr($klasse, '\\'), 1) oder über explode() samt end(). Alle drei liefern bei App\Models\Benutzer den Wert Benutzer. Woher die Trennzeichen stammen, beschreibt das Tutorial zu PHP Namespaces.

In einem Trait gibt es keine Überraschung: genannt wird die Klasse, die den Trait einbindet, und bei Vererbung die Kindklasse. Der Trait selbst taucht nie auf, was zum Wesen von Traits in PHP passt, denn sie sind kein eigener Typ.

<?php

trait NennMich
{
public static function name(): string
{
return get_called_class();
}
}

class A
{
use NennMich;
}

class B extends A {}

echo A::name(); /* A */
echo B::name(); /* B */

Bei anonymen Klassen wird das Ergebnis unbrauchbar. Der Name beginnt mit class@anonymous und trägt danach Dateipfad und Zeilennummer. Als Schlüssel oder Tabellenname taugt das nichts, weil sich der Wert mit jeder Verschiebung im Quelltext ändert.

Der Aufruf außerhalb einer Klasse

Steht der Aufruf im Skript statt in einer Klasse, gibt es nichts zu ermitteln. Bis PHP 7 kam ein false samt Warnung heraus, seit PHP 8 wirft PHP get_called_class() einen Error. Deshalb greifen alte Abfragen auf false heute nie mehr: das Programm steht schon, bevor der Vergleich an der Reihe ist.

<?php

/* Bis PHP 7: Rueckgabe false plus Warnung.
Ab PHP 8: Error. */
try {
var_dump(get_called_class());
} catch (\Error $e) {
echo $e->getMessage();
/* get_called_class() must be called
from within a class */
}

get_parent_class() als Gegenstück

Die Frage nach der Elternklasse beantwortet eine eigene Funktion. get_parent_class() nennt deren Namen oder gibt false heraus, wenn es keine gibt. Zusammen ergibt das get_parent_class(get_called_class()). Diese Kombination steht allerdings in einer Methode, denn auf Dateiebene bricht PHP get_called_class() mit einem Error ab.

Der Haken sitzt genau dort, wo man ihn nach diesem Tutorial vermutet. Ohne Argument bezieht sich die Funktion auf die Klasse, in der der Code steht, nicht auf die angesprochene. Derselbe Denkfehler wie bei self, nur an anderer Stelle.

<?php

class Basis
{
public function eltern(): string
{
/* Ohne Argument gilt die Klasse, in der
der Code steht. Seit PHP 8.3 meldet
PHP hier zusaetzlich Deprecated. */
return var_export(get_parent_class(), true);
}

public static function elternRichtig(): string
{
return var_export(
get_parent_class(get_called_class()),
true
);
}
}

class Kind extends Basis {}

echo (new Kind())->eltern();
/* false, nicht 'Basis' */

/* Richtig: immer mit Argument */
echo var_export(get_parent_class('Kind'), true);
/* 'Basis' */

echo Kind::elternRichtig(); /* 'Basis' */
echo Basis::elternRichtig(); /* false */

Das false in der ersten Ausgabe verwirrt beim Lesen, ist aber folgerichtig: gefragt wurde nach der Elternklasse von Basis, und die hat keine. Wie bei get_class() ist der argumentlose Aufruf seit PHP 8.3 abgekündigt. Ein Argument steht also ohnehin an, entweder static::class oder das Ergebnis von PHP get_called_class().

self::, static:: und die Funktion trennen sich an einer einzigen Frage: was mit dem Namen danach geschehen soll.

flowchart TD
    A[Aufruf Kind::methode] --> B{Welche Form?}
    B -->|self::| C[Immer die Basisklasse]
    B -->|static::| D[Aufgerufene Klasse]
    B -->|get_called_class| E[Name als String]
    D --> F{Instanz erzeugen?}
    F -->|Ja| G[new static aufrufen]
    F -->|Nein| H[static::class nutzen]
    E --> I{Name weiterverwenden?}
    I -->|Nur Anzeige| H
    I -->|Elternklasse| J[get_parent_class]

Stolperfallen im Überblick

self bindet früh, static bindet spät. Aus diesem einen Unterschied entstehen sechs wiederkehrende Einträge in Fehlerberichten zu PHP get_called_class().

Der Name der Basisklasse gilt als Fehler

Ein self::class in einer geerbten Methode nennt die Klasse, in der die Zeile steht. Das ist festgelegtes Verhalten, kein Versehen.

Eine Fabrikmethode erzeugt mit new self()

Dann kommt das Objekt der Basisklasse heraus. Ist sie abstrakt, endet derselbe Aufruf mit Cannot instantiate abstract class.

Der Rückgabetyp lautet self statt static

Die Kette gibt die Basisklasse als Typ aus, obwohl zur Laufzeit ein Kindobjekt unterwegs ist. Die Autovervollständigung verliert den Anschluss.

Der Namensraum wandert in den Tabellennamen

Ohne Abschneiden entsteht aus App\Models\Benutzer ein Name, den keine Datenbank kennt.

Eine private statische Eigenschaft dient als Ablage

Alle Kindklassen teilen sie sich. Wer je Kindklasse etwas ablegen will, braucht ein Array mit dem Klassennamen als Schlüssel.

Ein fester Klassenname unterbricht die Weitergabe

Nur weiterleitende Aufrufe reichen den Namen durch. Ein Basis::ziel() setzt den Kontext zurück, static::ziel() nicht.

Fazit

PHP get_called_class() nennt die Klasse, über die eine Methode angesprochen wurde, und löst damit das Missverständnis vom Anfang auf. self bindet an die Klasse, in der die Zeile steht, static an die aufgerufene. Nur im statischen Kontext trennen sich die Wege.

Für die tägliche Arbeit bleiben vier Handgriffe. In Fabrikmethoden steht new static() statt new self(), dazu static als Rückgabetyp. Der voll qualifizierte Name wird abgeschnitten, bevor daraus ein Tabellenname wird. Außerhalb einer Klasse wirft der Aufruf seit PHP 8 einen Error. Und in neuem Code steht static::class, weil die statische Analyse damit umgehen kann. Veraltet ist PHP get_called_class() deswegen nicht.

 

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.