Start · Sprachen · PHP · Referenz · ReflectionReference

ReflectionReference

Klasse

Liefert Informationen über PHP-Referenzen und ermöglicht die Identifikation von Variablen, die auf dieselbe Referenz zeigen.

seit PHP 7.4.0 Kategorie: oop

Signatur

class ReflectionReference

Beschreibung

ReflectionReference ist eine Reflection-Klasse, die es erlaubt, Referenzbeziehungen zwischen PHP-Variablen zu untersuchen. Sie wurde in PHP 7.4 eingeführt und ist besonders nützlich, um festzustellen, ob zwei oder mehr Variablen auf dasselbe referenzierte Symbol zeigen.

Die Klasse kann nicht direkt instanziiert werden. Stattdessen wird eine Instanz über die statische Fabrikmethode ReflectionReference::fromArrayElement() erstellt, indem ein Array-Element übergeben wird, das eine Referenz enthält. Handelt es sich bei dem Element um keine Referenz, gibt die Methode null zurück.

Der Hauptanwendungsfall ist die Ermittlung einer eindeutigen Referenz-ID über getId(). Zwei ReflectionReference-Objekte, deren IDs übereinstimmen, zeigen auf dieselbe zugrunde liegende Variable. Dies ist besonders beim Debuggen von Datenstrukturen, beim Serialisieren von Objektgraphen oder beim Zirkulärreferenz-Erkennen hilfreich.

Da PHP intern Referenzen als sogenannte zval-Container verwaltet, ist die zurückgegebene ID keine stabile, persistente Adresse, sondern nur innerhalb eines einzelnen Skript-Laufs und ohne dazwischenliegende Garbage-Collection verlässlich vergleichbar.

Beispiele

Zwei Variablen auf dieselbe Referenz prüfen

<?php
$a = 'Hallo';
$b = &$a;

$arr = [&$a, &$b];

$ref0 = ReflectionReference::fromArrayElement($arr, 0);
$ref1 = ReflectionReference::fromArrayElement($arr, 1);

if ($ref0 !== null && $ref1 !== null) {
    if ($ref0->getId() === $ref1->getId()) {
        echo 'Beide Elemente zeigen auf dieselbe Referenz.' . PHP_EOL;
    } else {
        echo 'Die Elemente sind unterschiedliche Referenzen.' . PHP_EOL;
    }
}
Beide Elemente zeigen auf dieselbe Referenz.

Kein Referenz-Element – fromArrayElement gibt null zurück

<?php
$arr = ['foo', 'bar'];

$ref = ReflectionReference::fromArrayElement($arr, 0);

if ($ref === null) {
    echo 'Das Element ist keine Referenz.' . PHP_EOL;
} else {
    echo 'Referenz-ID: ' . $ref->getId() . PHP_EOL;
}
Das Element ist keine Referenz.

Zirkuläre Referenzen in einer Datenstruktur erkennen

<?php
$data = [];
$data[] = &$data; // Zirkuläre Referenz

$ids = [];

foreach ($data as $key => $value) {
    $ref = ReflectionReference::fromArrayElement($data, $key);
    if ($ref !== null) {
        $id = $ref->getId();
        if (in_array($id, $ids, true)) {
            echo "Zirkuläre Referenz bei Index $key entdeckt (ID: $id)" . PHP_EOL;
        } else {
            $ids[] = $id;
        }
    }
}
Zirkuläre Referenz bei Index 0 entdeckt (ID: ...)

// Wichtig · Fallstricke

Stabilität der ID: Die von getId() zurückgegebene ID ist nur innerhalb des aktuellen Skript-Laufs stabil. Sie darf nicht serialisiert oder über Prozessgrenzen hinweg verglichen werden. Garbage-Collection-Zyklen können dazu führen, dass eine ID wiederverwendet wird.

Keine direkte Instanziierung: Der Konstruktor von ReflectionReference ist privat; Instanzen dürfen ausschließlich über ReflectionReference::fromArrayElement() erstellt werden. Der Versuch, new ReflectionReference() aufzurufen, führt zu einem Fehler.

Nur Array-Elemente: Aktuell unterstützt die Klasse ausschließlich Array-Elemente als Eingabe. Referenzen auf Objekt-Eigenschaften oder Variablen können nicht direkt übergeben werden; als Workaround kann man sie zunächst in ein Array packen.