„Deprecated: Creation of dynamic property … is deprecated“ – was tun nach dem Update auf PHP 8.2?
Nach dem Update auf PHP 8.2 ist das Log voller „Creation of dynamic property“-Meldungen? Was die Warnung bedeutet und wie Sie sie sauber beheben – mit Codebeispielen.
Kurz gesagt: Die Meldung „Deprecated: Creation of dynamic property … is deprecated“ bedeutet, dass Ihr Code einem Objekt eine Eigenschaft zuweist, die in der Klasse nicht deklariert ist. Seit PHP 8.2 ist das als veraltet markiert. Ihre Website läuft weiter, aber das Verhalten soll in einer künftigen Hauptversion von PHP wegfallen. Die saubere Lösung ist, die Eigenschaft in der Klasse zu deklarieren. Als Übergang hilft das Attribut #[\AllowDynamicProperties].
Die Meldung taucht fast immer direkt nach einem PHP-Update auf. Der Hoster stellt von 8.1 auf 8.2 oder neuer um – und plötzlich ist das Fehlerprotokoll voll, oder die Hinweise stehen sogar sichtbar oben auf der Seite. Vollständig sieht sie so aus:
Deprecated: Creation of dynamic property Rechnung::$kunde is deprecated
in /var/www/html/classes/Rechnung.php on line 14
Die Meldung nennt Ihnen also die Klasse (Rechnung), die Eigenschaft ($kunde), die Datei und die Zeile. Damit lässt sich gut arbeiten.
Was ist eine „dynamische Eigenschaft“?
In PHP konnte man jahrzehntelang einem Objekt einfach eine neue Eigenschaft zuweisen, auch wenn die Klasse sie nicht kennt. PHP hat sie dann stillschweigend angelegt. Ein typisches Beispiel aus älterem Code:
class Rechnung
{
public $nummer;
public function __construct($nummer, $kunde)
{
$this->nummer = $nummer;
$this->kunde = $kunde; // $kunde ist nicht deklariert
}
}
$nummer ist oben in der Klasse deklariert, $kunde nicht. Bis PHP 8.1 lief das ohne jeden Hinweis. Seit PHP 8.2 erzeugt genau diese Zeile die Deprecated-Meldung.
Warum hat PHP das geändert? Dynamische Eigenschaften verstecken Tippfehler. Schreibt jemand $this->kudne statt $this->kunde, legt PHP einfach eine neue Eigenschaft an – und der Fehler fällt erst viel später auf, an einer ganz anderen Stelle. Mit deklarierten Eigenschaften sehen Sie solche Fehler sofort.
Nicht betroffen sind Objekte vom Typ stdClass (zum Beispiel das Ergebnis von json_decode() ohne zweiten Parameter) und Klassen, die die magischen Methoden __get und __set verwenden.
Ist das gefährlich?
Heute nicht direkt. „Deprecated“ ist eine Vorwarnung, kein Fehler. Der Code macht unter PHP 8.2, 8.3 und 8.4 genau das, was er vorher gemacht hat.
Die Vorwarnung hat aber einen Zweck: Das PHP-Projekt plant, dynamische Eigenschaften in einer künftigen Hauptversion nicht mehr zu erlauben. Wann genau das kommt und in welcher Form, ist heute noch nicht endgültig festgelegt. Sicher ist nur die Richtung. Wenn es so weit ist, wird aus der Meldung ein echter Fehler, und betroffene Seiten brechen ab.
Zwei Probleme gibt es schon heute:
- Sichtbare Meldungen: Ist
display_errorsauf dem Server aktiv, erscheinen die Hinweise im Browser. Das sieht unprofessionell aus und verrät Pfade auf Ihrem Server. - Volle Logdateien: Wird eine betroffene Klasse bei jedem Seitenaufruf benutzt, wächst das Fehlerprotokoll schnell. Echte Fehler gehen darin unter.
Lösung 1: Die Eigenschaft deklarieren
Das ist der richtige Weg, und meistens ist er auch der einfachste. Sie ergänzen die fehlende Eigenschaft oben in der Klasse:
class Rechnung
{
public $nummer;
public $kunde;
public function __construct($nummer, $kunde)
{
$this->nummer = $nummer;
$this->kunde = $kunde;
}
}
Fertig. Die Sichtbarkeit (public, protected, private) richtet sich danach, wer auf die Eigenschaft zugreift. Wenn anderer Code von außen $rechnung->kunde liest, muss sie public bleiben.
Ein Hinweis aus der Praxis: Wenn Sie bei der Gelegenheit Typen ergänzen, etwa public string $kunde;, hat die Eigenschaft keinen Startwert mehr. Wird sie gelesen, bevor sie gesetzt wurde, bricht PHP mit einem Fehler ab („must not be accessed before initialization“). Bei altem Code setze ich deshalb zuerst nur die Deklaration ohne Typ oder mit Standardwert, zum Beispiel public ?string $kunde = null;.
Lösung 2: #[\AllowDynamicProperties] als Übergang
Manchmal hat eine Klasse Dutzende solcher Stellen, oder die Eigenschaften werden aus Datenbankspalten erzeugt und sind vorher nicht bekannt. Dann können Sie die Klasse ausdrücklich freigeben:
#[\AllowDynamicProperties]
class Rechnung
{
public $nummer;
// ...
}
Damit verschwindet die Meldung für diese Klasse und alle Klassen, die von ihr erben. Unter PHP 7.x wird die Zeile als Kommentar gelesen, der Code bleibt also auch dort lauffähig.
Ich nutze das Attribut nur als Übergangslösung. Es schaltet die Warnung ab, behebt aber nicht die Ursache. Wenn Sie es einsetzen, notieren Sie sich die Stellen und planen Sie die eigentliche Korrektur ein.
Lösung 3: __get und __set für wirklich dynamische Daten
Es gibt Klassen, die bewusst beliebige Werte aufnehmen sollen, zum Beispiel Einstellungen oder Datensätze aus der Datenbank. Hier ist es sauberer, die Werte in einem Array zu speichern und den Zugriff über magische Methoden zu regeln:
class Einstellungen
{
private array $daten = [];
public function __get(string $name): mixed
{
return $this->daten[$name] ?? null;
}
public function __set(string $name, mixed $value): void
{
$this->daten[$name] = $value;
}
public function __isset(string $name): bool
{
return isset($this->daten[$name]);
}
public function __unset(string $name): void
{
unset($this->daten[$name]);
}
}
Der restliche Code kann weiter $einstellungen->farbe = 'blau'; schreiben, es entsteht aber keine dynamische Eigenschaft mehr. Vergessen Sie __isset nicht – sonst liefern isset() und empty() falsche Ergebnisse. Alternativ reicht oft ein einfaches Array oder ein stdClass-Objekt.
So finden Sie alle betroffenen Stellen
Gehen Sie nicht einzeln jede Meldung im Browser durch. Schneller geht es über das Fehlerprotokoll. Auf der Kommandozeile fasst dieser Befehl alle betroffenen Klassen und Eigenschaften zusammen:
grep -o "Creation of dynamic property [^ ]*" error.log | sort | uniq -c | sort -rn
Sie bekommen eine Liste wie 312 Creation of dynamic property Rechnung::$kunde – mit der Anzahl der Vorkommen. So sehen Sie, welche Klassen Sie zuerst angehen sollten. Wichtig: Das Protokoll zeigt nur Stellen, die tatsächlich aufgerufen wurden. Selten genutzte Funktionen wie ein Jahresabschluss oder ein Export tauchen erst auf, wenn jemand sie benutzt. Klicken Sie deshalb auf einer Testkopie alle wichtigen Abläufe einmal durch.
Warum Sie die Meldung nicht einfach ausblenden sollten
Der schnellste „Fix“, der im Netz oft empfohlen wird, ist diese Zeile:
error_reporting(E_ALL & ~E_DEPRECATED);
Danach ist Ruhe. Das Problem ist aber nicht weg, Sie sehen es nur nicht mehr. Und Sie verlieren genau die Vorwarnung, die Ihnen Zeit für die Umstellung verschaffen soll. Außerdem blenden Sie damit alle anderen Deprecated-Meldungen gleich mit aus – auch die, die Sie beim nächsten PHP-Update dringend sehen müssten.
Man muss zwei Dinge auseinanderhalten:
- Anzeige im Browser: Auf einer Live-Website sollte
display_errorsimmer aus sein. Das ist richtig und hat mit dieser Meldung nichts zu tun. - Protokollierung:
log_errorssollte an bleiben, und Deprecated-Meldungen gehören ins Log. Nur so wissen Sie, was beim nächsten Update bricht.
Typische Fehler bei der Korrektur
- Fremden Code direkt ändern: Kommt die Meldung aus einem Plugin, einer Erweiterung oder dem Ordner
vendor/, wird Ihre Änderung beim nächsten Update überschrieben. Prüfen Sie zuerst, ob es eine neuere Version gibt. Wenn nicht, melden Sie das Problem beim Hersteller. - Attribut überall verteilen:
#[\AllowDynamicProperties]auf jede Klasse zu setzen, macht die Meldungen stumm, verschiebt das Problem aber nur. - Falsche Sichtbarkeit: Wer die Eigenschaft als
privatedeklariert, obwohl anderer Code von außen darauf zugreift, erzeugt einen echten Fehler. - Direkt auf dem Live-System arbeiten: Ein Tippfehler in einer zentralen Klasse legt die ganze Website lahm. Ändern und testen Sie auf einer Kopie.
Wann Sie Hilfe brauchen
Bei einer Handvoll Meldungen in Ihrem eigenen Code schaffen Sie die Korrektur mit dieser Anleitung selbst. Anders sieht es aus, wenn das Log Hunderte verschiedene Klassen zeigt, wenn der Code von einem Entwickler stammt, der nicht mehr erreichbar ist, oder wenn neben den Deprecated-Hinweisen auch echte Fehler auftauchen. Dann lohnt sich ein geordnetes Vorgehen.
Ich prüfe das Fehlerprotokoll, sortiere die Meldungen nach Dringlichkeit und korrigiere sie auf einer Testkopie, bevor etwas live geht. Wenn es nur um einzelne Fehler geht, finden Sie Ablauf und Preise unter PHP-Fehler beheben (Analyse 150 €, Behebung ab 290 €). Steht ohnehin ein Wechsel auf eine neuere PHP-Version an, ist die PHP-Aktualisierung (ab 690 €) der passende Rahmen – dann wird der Code einmal gründlich für die neue Version vorbereitet.