Start · Sprachen · PHP · Referenz · uopz_compose

uopz_compose

Funktion

Erstellt zur Laufzeit dynamisch eine neue Klasse aus angegebenen Basisklassen, Methoden und Eigenschaften.

seit PHP 5.0.0 Kategorie: misc

Signatur

uopz_compose(string $name, array $bases, array $methods = [], array $properties = [], int $flags = ZEND_ACC_CLASS): bool

Beschreibung

uopz_compose ist Teil der UOPZ-Extension (User Operations for Zend) und ermöglicht es, vollständige PHP-Klassendefinitionen programmatisch zur Laufzeit zusammenzusetzen. Die Funktion registriert eine neue Klasse im Zend-Engine-Klassenregister, als wäre sie bereits im Quellcode definiert worden.

Man übergibt einen Klassennamen, ein Array von Basisklassen oder Interfaces (die vererbt bzw. implementiert werden sollen), ein optionales Array von Methoden-Closures, ein optionales Array von Eigenschaften sowie optionale Flags für den Klassentyp (z. B. abstrakt oder final). Dies macht die Funktion vor allem in Test-Setups, Mocking-Frameworks und dynamischen Proxy-Szenarien nützlich, wo Klassen zur Laufzeit ohne eval() erzeugt werden sollen.

Jede übergebene Methode wird als Closure übergeben und der neuen Klasse zugewiesen. Das Properties-Array akzeptiert assoziative Einträge der Form 'eigenschaftsName' => Wert. Der flags-Parameter erlaubt die Angabe von Sichtbarkeits- und Klassen-Flags, wie sie intern von der Zend Engine verwendet werden.

Wichtig: uopz_compose steht nur zur Verfügung, wenn die UOPZ-Extension installiert und geladen ist. Sie ist nicht für den Produktionseinsatz gedacht, sondern primär für Tests und Entwicklungsumgebungen.

Parameter

Name Typ Default Beschreibung
$name Pflicht string Der vollqualifizierte Name der neu zu erstellenden Klasse.
$bases Pflicht array Ein Array von Klassen- oder Interface-Namen, von denen die neue Klasse erben oder die sie implementieren soll. Das erste Element gilt als Elternklasse, weitere Elemente werden als Interfaces behandelt.
$methods array [] Ein assoziatives Array der Form 'methodenName' => Closure, das die Methoden der neuen Klasse definiert.
$properties array [] Ein assoziatives Array der Form 'eigenschaftsName' => Standardwert, das die Eigenschaften (Properties) der neuen Klasse definiert.
$flags int ZEND_ACC_CLASS Interne Zend-Engine-Flags, z. B. für abstrakte oder finale Klassen. Standardmäßig wird eine gewöhnliche Klasse erstellt.

Rückgabewert

Typ
bool
Beschreibung
Gibt true zurück, wenn die Klasse erfolgreich erzeugt wurde, andernfalls false.

Beispiele

Einfache Klasse dynamisch erstellen

<?php
// Voraussetzung: UOPZ-Extension ist geladen

interface Greetable {
    public function greet(): string;
}

uopz_compose(
    'DynamicGreeter',
    ['Greetable'],
    [
        'greet' => function(): string {
            return 'Hallo aus einer dynamisch erstellten Klasse!';
        }
    ]
);

$obj = new DynamicGreeter();
echo $obj->greet();
Hallo aus einer dynamisch erstellten Klasse!

Klasse mit Basisklasse und Properties zusammensetzen

<?php
// Voraussetzung: UOPZ-Extension ist geladen

class BaseEntity {
    public function getType(): string {
        return 'entity';
    }
}

uopz_compose(
    'UserEntity',
    ['BaseEntity'],
    [
        'getLabel' => function(): string {
            return 'Benutzer: ' . $this->name;
        }
    ],
    [
        'name' => 'Max Mustermann',
        'active' => true
    ]
);

$user = new UserEntity();
echo $user->getType() . PHP_EOL; // Geerbt von BaseEntity
echo $user->getLabel() . PHP_EOL;
entity Benutzer: Max Mustermann

// Wichtig · Fallstricke

Nur für Entwicklung und Tests: uopz_compose ist ein mächtiges Werkzeug, das direkt in den internen Klassenregister der Zend Engine eingreift. Der Einsatz im Produktionsbetrieb ist nicht empfohlen, da unvorhersehbare Seiteneffekte auftreten können.

Die UOPZ-Extension muss explizit installiert werden (z. B. via PECL: pecl install uopz). Nicht alle PHP-Versionen und Serverkonfigurationen unterstützen sie gleichermaßen. Ab UOPZ 6.x wurden einige APIs geändert oder entfernt – prüfe die Kompatibilität mit der verwendeten PHP-Version.

Da einmal zusammengesetzte Klassen im Klassenregister verbleiben, können sie innerhalb desselben Request-Lebenszyklus nicht neu definiert werden, ohne Fehler zu erzeugen.