Signatur
Beschreibung
Componere\Definition ist der zentrale Baustein der Componere-PHP-Erweiterung und erlaubt es, zur Laufzeit vollständig neue Klassen zu definieren oder bestehende Klassen um Methoden, Schnittstellen und Traits zu erweitern – ohne den PHP-Quellcode zu verändern. Dies ist besonders nützlich für Monkey-Patching in Testumgebungen, für dekorative Erweiterungen in Plugin-Architekturen oder für dynamisches Verhalten, das erst zur Laufzeit bekannt ist.
Eine Definition wird erstellt, indem man optional eine Elternklasse und/oder eine oder mehrere Schnittstellen übergibt. Anschließend lassen sich mit Methoden wie addMethod(), addTrait() und addInterface() Verhaltensweisen hinzufügen. Mit register() wird die Definition endgültig in der PHP-Laufzeitumgebung registriert und die Klasse damit verwendbar.
Sobald eine Definition registriert wurde, ist sie unveränderlich – weitere Anpassungen sind nicht mehr möglich. Es empfiehlt sich daher, alle gewünschten Ergänzungen vor dem Aufruf von register() vorzunehmen. Nicht registrierte Definitionen haben keinerlei Auswirkungen auf laufende Programme.
Hinweis: Die Componere-Erweiterung ist eine PECL-Erweiterung und muss separat installiert werden. Sie ist nicht Bestandteil der PHP-Standardinstallation.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $name Pflicht | string | Der vollqualifizierte Name der neuen Klasse, die definiert werden soll, z. B. "MyNamespace\\MyClass". |
|
| $parent | string | Optionaler Name der Elternklasse, von der die neue Definition erben soll. Muss eine bereits existierende, geladen Klasse sein. | |
| $interfaces | array | [] | Optionales Array mit Schnittstellennamen (als Strings), die die neue Klasse implementieren soll. |
Beispiele
Neue Klasse zur Laufzeit definieren und registrieren
<?php
use Componere\Definition;
use Componere\Method;
// Neue Klasse 'Greeter' zur Laufzeit definieren
$definition = new Definition('Greeter');
// Methode 'greet' hinzufügen
$definition->addMethod('greet', new Method(function (string $name): string {
return "Hallo, " . $name . "!";
}));
// Definition registrieren – ab jetzt ist 'Greeter' nutzbar
$definition->register();
$greeter = new Greeter();
echo $greeter->greet('Welt');
// Ausgabe: Hallo, Welt!
Klasse mit Elternklasse und Interface zur Laufzeit erstellen
<?php
use Componere\Definition;
use Componere\Method;
interface Serializable2 {
public function serialize2(): string;
}
class BaseEntity {
protected int $id;
public function __construct(int $id) {
$this->id = $id;
}
}
// 'UserEntity' erbt von 'BaseEntity' und implementiert 'Serializable2'
$definition = new Definition('UserEntity', 'BaseEntity', ['Serializable2']);
$definition->addMethod('serialize2', new Method(function (): string {
return json_encode(['id' => $this->id]);
}));
$definition->register();
$user = new UserEntity(42);
echo $user->serialize2();
// Ausgabe: {"id":42}
Bestehende Klasse um eine Methode erweitern (Monkey-Patching)
<?php
use Componere\Definition;
use Componere\Method;
class Calculator {
public function add(int $a, int $b): int {
return $a + $b;
}
}
// Bestehende Klasse 'Calculator' zur Laufzeit erweitern
$definition = new Definition('Calculator');
$definition->addMethod('multiply', new Method(function (int $a, int $b): int {
return $a * $b;
}));
$definition->register();
$calc = new Calculator();
echo $calc->add(3, 4) . PHP_EOL; // Vorhandene Methode
echo $calc->multiply(3, 4) . PHP_EOL; // Neu hinzugefügte Methode
// Wichtig · Fallstricke
Unveränderlichkeit nach Registrierung: Sobald register() aufgerufen wurde, kann die Definition nicht mehr verändert werden. Jeder weitere Versuch, z. B. addMethod() aufzurufen, löst eine Componere\Exception aus.
Gültigkeitsbereich: Registrierte Definitionen gelten für die gesamte Laufzeit des PHP-Prozesses. Bei Verwendung in einem Web-Server-Kontext (z. B. unter PHP-FPM oder Apache mit mod_php) gilt die Definition für den gesamten Request. Eine Aufhebung der Registrierung ist nicht möglich.
Testumgebungen: Die Componere-Erweiterung wird häufig in Testkontexten genutzt, um Klassen zu mocken oder um inkompatible Legacy-Klassen anzupassen, ohne deren Quellcode zu ändern. Für Produktivumgebungen sollte der Einsatz sorgfältig abgewogen werden, da dynamische Klassendefinitionen die Lesbarkeit und Wartbarkeit des Codes erschweren können.
Installation: Componere ist eine PECL-Erweiterung: pecl install componere. Sie erfordert PHP 7.1 oder höher und ist nicht mit allen PHP-Konfigurationen kompatibel (z. B. ZTS-Builds).