Skip to the content
Documentation
Help Start
Reading in:
  • German: 9,075 of 9,075 pages
About the help in other languages
All help pages

Dynamische Eigenschaften

PHP 8.2 markiert Eigenschaften, die eine Klasse nicht deklariert, als veraltet. Wie der Kernel sie bei persistenten Objekten behandelt, wie Sie sie in Ihren eigenen Klassen finden und wann Sie sie deklarieren, ein Array…

Download as PDF

Address: https://doc.exponential.earth/exphelp/viewer/help/extension-development/part-4-upgrading/dynamic-properties.md

On this page

This page is a translation. Read the English original

Dynamische Eigenschaften

Teil 4, Kapitel 9. In PHP vor 8.2 konnten Sie jede Eigenschaft auf jedem Objekt setzen: $this->cache = array(); hat cache angelegt, wenn die Klasse es nicht deklarierte. PHP 8.2 meldet das als veraltet:

Deprecated: Creation of dynamic property myOldExtHandler::$cache is deprecated

Alte Erweiterungen tun das überall, weil Code für PHP 4 und PHP 5 Eigenschaften oft nur in Kommentaren aufgeführt hat. Dieses Kapitel erklärt, was der Kernel bereits für Sie erledigt und wie Sie Ihre eigenen Klassen korrigieren.

Was der Kernel bereits erledigt

Drei Kernel-Klassen erlauben dynamische Eigenschaften bewusst, mit dem PHP-Attribut #[AllowDynamicProperties]:

KlasseWarum
eZPersistentObject (kernel/classes/ezpersistentobject.php)die Felder einer Zeile werden namentlich als Eigenschaften gesetzt
eZWorkflowProcessdasselbe, für Workflow-Prozesse
eZINI (lib/ezutils/classes/ezini.php)alter Code setzt Eigenschaften auf Einstellungsobjekten

eZPersistentObject geht noch weiter: Es hat die Methoden __get(), __set(), __isset() und __unset(), die nicht deklarierte Felder in einem geschützten Array halten, sodass eine Unterklasse, die sich auf dynamische Felder verlässt, die Deprecation nicht auslöst. Der Kernel hat das in 6.0.4 eingeführt (PHP-8-Unterstützung).

Eine Ihrer Klassen, die eZPersistentObject erweitert, braucht also meist nichts. Jede andere Klasse schon.

Sie finden

PHP meldet sie erst, wenn die Zeile ausgeführt wird. Um sie vorher zu finden, vergleichen Sie, was eine Klasse setzt, mit dem, was sie deklariert. Das ist ein grober, aber nützlicher Anfang:

cd extension/myoldext
for f in $(grep -rlE '^\s*class\s' --include='*.php' .); do
  set=$(grep -oE '\$this->[A-Za-z_][A-Za-z0-9_]*\s*=[^=]' "$f" | sed -E 's/\$this->([A-Za-z0-9_]+).*/\1/' | sort -u)
  for p in $set; do
    grep -qE "(public|protected|private|var)\s+(\??[A-Za-z_\\]+\s+)?\\\$$p\b" "$f" || echo "$f: \$$p"
  done
done

Es gibt jedes $this->x = ... aus, dessen x dieselbe Datei nicht deklariert. Eine in einer Elternklasse deklarierte Eigenschaft erscheint ebenfalls; prüfen Sie diese gegen die Elternklasse.

Der sichere Weg ist, die Erweiterung unter PHP 8.2 oder neuer mit eingeschalteter Debug-Ausgabe laufen zu lassen und jede Seite, jede View und jedes Skript einmal zu verwenden.

Lösung 1: die Eigenschaft deklarieren (die übliche Lösung)

// before
class myOldExtHandler
{
    function __construct()
    {
        $this->cache = array();
        $this->ini = eZINI::instance( 'myoldext.ini' );
    }
}

// after
class myOldExtHandler
{
    /** @var array */
    protected $cache = array();

    /** @var eZINI */
    protected $ini;

    function __construct()
    {
        $this->ini = eZINI::instance( 'myoldext.ini' );
    }
}

Wählen Sie die Sichtbarkeit bewusst:

  • public, wenn Templates sie lesen. Die Template-Engine liest Objekte über attribute() und hasAttribute() (siehe Template-Operatoren), aber einige alte Klassen geben öffentliche Eigenschaften direkt preis.
  • protected für alles andere. Eine Unterklasse kann sie trotzdem verwenden.

Alter PHP-4-Code deklariert Eigenschaften mit var. var funktioniert weiterhin und bedeutet public; Sie können es stehen lassen oder zur Klarheit public schreiben.

Lösung 2: ein Array für Daten, die wirklich dynamisch sind

Wenn die Namen aus Daten stammen (die Spalten einer Importdatei, die Felder eines Formulars), legen Sie nicht für jeden Namen eine Eigenschaft an. Halten Sie sie in einem deklarierten Array:

<?php
class myOldExtRecord
{
    /** @var array<string, mixed> */
    protected $fields = array();

    public function set( string $name, $value ): void
    {
        $this->fields[$name] = $value;
    }

    public function get( string $name )
    {
        return $this->fields[$name] ?? null;
    }

    public function attributes(): array
    {
        return array_keys( $this->fields );
    }

    public function hasAttribute( $name ): bool
    {
        return array_key_exists( $name, $this->fields );
    }

    public function attribute( $name )
    {
        return $this->get( $name );
    }
}

Mit den letzten drei Methoden können Templates die Felder als $record.title lesen, so wie die Template-Engine Kernel-Objekte liest.

Lösung 3: sie erlauben, wenn es sein muss

Für eine Klasse, deren ganzer Entwurf von dynamischen Eigenschaften abhängt und die Sie jetzt nicht ändern können, markieren Sie sie:

#[AllowDynamicProperties]
class myOldExtLegacyContainer
{
}

Unter PHP 8.0 und 8.1 wird ein Attribut, das PHP nicht kennt, ignoriert, daher läuft das überall. Betrachten Sie es als Notiz an sich selbst: Die Klasse braucht trotzdem eine echte Lösung.

Objekte anderer Klassen

Bei der Deprecation geht es um die Klasse des Objekts, nicht darum, wer die Eigenschaft setzt. Eine Eigenschaft auf einem Kernel-Objekt aus Ihrer Erweiterung zu setzen, ist dasselbe Problem:

// deprecated: eZContentObjectTreeNode does not declare myoldextScore
// (eZContentObjectTreeNode extends eZPersistentObject, so in Exponential 6 this lands in its backing array)
$node->myoldextScore = 5;

Bei persistenten Objekten bleibt das in Exponential 6 zufällig ruhig, aber es ist zerbrechlich: Der Wert ist kein Feld, wird nicht gespeichert und kann verschwinden, wenn das Kernel-Objekt erneut geholt wird. Halten Sie Ihre eigenen Daten in Ihrer eigenen Struktur, zum Beispiel in einem Array mit der Knoten-ID als Schlüssel.

stdClass und Objekte aus json_decode() erlauben dynamische Eigenschaften per Definition und sind nicht betroffen.

Verwandte Seiten

Werden Sie Exponential-Partner

Partner teilen ihre Informationen, stellen Mittel bereit, geben Beiträge zurück und entwickeln die Produkte mit uns, und so wächst Exponential. Eine Partner-Website und ein Dashboard sind für Mitte 2027 geplant: Werden Sie noch heute Partner, damit wir schneller wachsen und neue Funktionen früher liefern.

Something wrong on this page? Report an error

Documentation license

This documentation is free documentation, licensed under the GNU Free Documentation License 1.3 or later.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x