Start · Sprachen · PHP · Referenz · ReflectionUnionType

ReflectionUnionType

Klasse

Liefert Informationen über einen Union-Typ (z. B. <code>int|string|null</code>) eines Parameters, Rückgabewerts oder Eigenschaften.

seit PHP 8.0.0 Kategorie: oop

Signatur

class ReflectionUnionType extends ReflectionType

Beschreibung

ReflectionUnionType ist eine Unterklasse von ReflectionType und repräsentiert einen PHP-Union-Typ, der seit PHP 8.0 mit dem Pipe-Operator (|) deklariert werden kann. Ein Union-Typ erlaubt es, mehrere mögliche Typen für einen Parameter, eine Eigenschaft oder einen Rückgabewert anzugeben, z. B. int|float|string.

Über die Reflection-API erhält man eine Instanz von ReflectionUnionType, wenn man bei einem ReflectionParameter, ReflectionProperty oder ReflectionFunctionAbstract die Methode getType() aufruft und der deklarierte Typ tatsächlich ein Union-Typ ist. Der wichtigste Unterschied zu ReflectionNamedType ist, dass ReflectionUnionType mehrere Typen enthält, die über getTypes() als Array abgerufen werden können.

Die Methode getTypes() liefert ein Array von ReflectionNamedType- oder ReflectionIntersectionType-Objekten (letzteres ab PHP 8.2 für Kombinationen wie (A&B)|null). Die Methode allowsNull(), geerbt von ReflectionType, gibt true zurück, wenn null Teil des Union-Typs ist.

Diese Klasse ist besonders nützlich für Code-Generatoren, Dependency-Injection-Container, Serialisierungs-Bibliotheken und Frameworks, die Typ-Informationen zur Laufzeit auswerten müssen.

Beispiele

Union-Typ eines Parameters per Reflection auslesen

<?php
function process(int|string|null $value): void {}

$ref   = new ReflectionFunction('process');
$param = $ref->getParameters()[0];
$type  = $param->getType();

if ($type instanceof ReflectionUnionType) {
    echo "Union-Typ gefunden:\n";
    foreach ($type->getTypes() as $t) {
        echo '  - ' . $t->getName() . "\n";
    }
    echo 'Erlaubt null: ' . ($type->allowsNull() ? 'Ja' : 'Nein') . "\n";
}
Union-Typ gefunden: - int - string - null Erlaubt null: Ja

Union-Rückgabetyp einer Methode analysieren

<?php
class Converter {
    public function convert(string $input): int|float|false {
        // ...
        return false;
    }
}

$method     = new ReflectionMethod(Converter::class, 'convert');
$returnType = $method->getReturnType();

if ($returnType instanceof ReflectionUnionType) {
    $names = array_map(
        fn(ReflectionNamedType $t) => $t->getName(),
        $returnType->getTypes()
    );
    echo 'Rückgabetypen: ' . implode(', ', $names) . "\n";
    echo 'Erlaubt null: ' . ($returnType->allowsNull() ? 'Ja' : 'Nein') . "\n";
}
Rückgabetypen: int, float, false Erlaubt null: Nein

Prüfen, ob ein Typ ein Union-Typ ist (PHP 8.2 DNF-Typen)

<?php
interface Stringable {}
interface Countable {}

class Demo {
    // DNF-Typ: (Stringable&Countable)|null  — erfordert PHP 8.2+
    public function handle((Stringable&Countable)|null $obj): void {}
}

$param = (new ReflectionMethod(Demo::class, 'handle'))
    ->getParameters()[0]
    ->getType();

echo get_class($param) . "\n";

foreach ($param->getTypes() as $t) {
    echo get_class($t) . ': ' . $t . "\n";
}
ReflectionUnionType ReflectionIntersectionType: Stringable&Countable ReflectionNamedType: null

// Wichtig · Fallstricke

Achtung: ?Foo (Nullable-Typ) ist intern kein Union-Typ, sondern ein ReflectionNamedType mit allowsNull() === true. Ein explizit geschriebener Foo|null hingegen ergibt eine ReflectionUnionType-Instanz.

Ab PHP 8.2 können sog. Disjunctive Normal Form (DNF)-Typen wie (A&B)|null deklariert werden. In diesem Fall gibt getTypes() auch ReflectionIntersectionType-Objekte zurück.

ReflectionUnionType kann nicht direkt instanziiert werden; Instanzen werden ausschließlich über die Reflection-API erzeugt.