Signatur
Beschreibung
runkit7_method_redefine() ermöglicht es, den Quellcode (oder eine Closure) einer bereits definierten Methode einer Klasse während der Programmausführung auszutauschen. Dies ist nützlich in Test-Szenarien (z. B. beim Monkey-Patching), beim dynamischen Anpassen von Klassen, die nicht über normale Vererbung oder Dependency Injection überschrieben werden können, oder beim Experimentieren in Entwicklungsumgebungen.
Die Funktion gehört zur runkit7-PECL-Extension, die speziell für die Manipulation von Klassen, Methoden und Funktionen zur Laufzeit entwickelt wurde. Sie ersetzt das Ursprungs-runkit für PHP 7+. Der neue Methodenkörper kann entweder als PHP-Code-String oder als Closure übergeben werden.
Der Parameter $flags steuert die Sichtbarkeit (RUNKIT7_ACC_PUBLIC, RUNKIT7_ACC_PROTECTED, RUNKIT7_ACC_PRIVATE) sowie optional RUNKIT7_ACC_STATIC. Diese Konstanten können mit dem bitweisen OR-Operator (|) kombiniert werden.
Achtung: Diese Funktion sollte niemals in Produktivsystemen eingesetzt werden. Sie ist ausschließlich für Entwicklungs- und Testzwecke gedacht, da das Ändern von Methoden zur Laufzeit zu unvorhersehbarem Verhalten, Debugging-Schwierigkeiten und Sicherheitsrisiken führen kann.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $classname Pflicht | string | Der Name der Klasse, deren Methode umdefiniert werden soll. | |
| $methodname Pflicht | string | Der Name der Methode innerhalb der Klasse, die neu definiert werden soll. | |
| $argument_list_or_closure Pflicht | string|Closure | Wird eine Closure übergeben, wird diese direkt als neuer Methodenkörper verwendet. Wird ein string übergeben, gilt dieser als Parameterliste (z. B. '$a, $b'), und der eigentliche Code wird über $code angegeben. |
|
| $code | string | Der PHP-Code-String für den Methodenkörper. Wird nur verwendet, wenn $argument_list_or_closure ein String ist. |
|
| $flags | int | RUNKIT7_ACC_PUBLIC | Sichtbarkeits- und Typflags. Mögliche Werte: RUNKIT7_ACC_PUBLIC, RUNKIT7_ACC_PROTECTED, RUNKIT7_ACC_PRIVATE, RUNKIT7_ACC_STATIC. Können mit | kombiniert werden. |
| $doc_comment | string | Optionaler DocComment-String, der der neuen Methode zugewiesen wird. | |
| $return_type | string | Optionale Typdeklaration für den Rückgabewert der neuen Methode (z. B. 'int' oder 'string'). |
|
| $is_strict | bool | false | Gibt an, ob die Methode im strikten Typmodus (declare(strict_types=1)) ausgeführt werden soll. |
Rückgabewert
true bei Erfolg zurück, false bei einem Fehler (z. B. wenn die Methode nicht existiert oder die Klasse nicht gefunden wird).Beispiele
Methode eines Objekts zur Laufzeit umdefinieren (String-Variante)
<?php
class Greeter {
public function hello(): string {
return 'Hallo Welt!';
}
}
$obj = new Greeter();
echo $obj->hello() . PHP_EOL; // Ausgabe: Hallo Welt!
runkit7_method_redefine(
'Greeter',
'hello',
'',
'return "Guten Tag, PHP!";',
RUNKIT7_ACC_PUBLIC
);
echo $obj->hello() . PHP_EOL; // Ausgabe: Guten Tag, PHP!
Methode mit einer Closure ersetzen (für Unit-Tests)
<?php
class PaymentService {
public function charge(float $amount): string {
// Echte Zahlungslogik ...
return 'charged:' . $amount;
}
}
// Im Testkontext: Methode durch Stub ersetzen
runkit7_method_redefine(
'PaymentService',
'charge',
Closure::fromCallable(function(float $amount): string {
return 'mocked:' . $amount;
})
);
$svc = new PaymentService();
echo $svc->charge(49.99); // Ausgabe: mocked:49.99
// Wichtig · Fallstricke
Nur für Entwicklung und Tests: Der Einsatz von runkit7_method_redefine() in Produktivumgebungen ist gefährlich und wird ausdrücklich nicht empfohlen. Das nachträgliche Ändern von Methoden kann den opcode-Cache (z. B. OPcache) umgehen oder inkonsistente Zustände verursachen.
Die Funktion setzt voraus, dass die PECL-Extension runkit7 installiert und in der php.ini aktiviert ist (extension=runkit7). Außerdem muss runkit7.internal_override = On gesetzt sein, wenn interne PHP-Funktionen oder -Methoden überschrieben werden sollen.
Bei bestehenden Objektinstanzen wirkt sich die Umdefinierung sofort aus, da PHP Methoden zur Laufzeit über die Klassenstruktur auflöst. Eine Umdefinierung einer Methode in einem Elternteil hat keinen Einfluss auf Kindklassen, die die Methode bereits überschrieben haben.