Start · Sprachen · PHP · Referenz · uopz_overload

uopz_overload

Funktion

Überschreibt einen PHP-VM-Opcode mit einem benutzerdefinierten Handler, um das Verhalten bei der Ausführung dieses Opcodes zu verändern.

seit PHP 2.0.0 Kategorie: misc

Signatur

uopz_overload(int $opcode, callable|null $handler): void

Beschreibung

uopz_overload() gehört zur UOPZ-Extension (User Operations) und ermöglicht es, einzelne Opcodes der Zend-VM durch eigene PHP-Callables zu ersetzen. Dadurch lässt sich das Laufzeitverhalten von PHP auf sehr niedriger Ebene beeinflussen — z. B. können new-Instanziierungen, Methodenaufrufe oder exit-Aufrufe abgefangen und modifiziert werden.

Dies ist primär für Testzwecke gedacht: In Unit-Tests kann damit etwa verhindert werden, dass exit/die den Testlauf abbricht, oder es kann geprüft werden, welche Objekte instanziiert werden. Der übergebene Handler wird anstelle des originalen Opcodes ausgeführt.

Um einen zuvor gesetzten Overload wieder zu entfernen, übergibt man null als zweiten Parameter. Dies stellt das ursprüngliche VM-Verhalten für den betreffenden Opcode wieder her.

Achtung: Ab UOPZ 5.x wurde uopz_overload() entfernt und durch spezifischere Funktionen wie uopz_set_return() ersetzt. Die Funktion ist daher nur in älteren UOPZ-Versionen verfügbar und sollte in neuen Projekten nicht mehr eingesetzt werden.

Parameter

Name Typ Default Beschreibung
$opcode Pflicht int Der zu überschreibende VM-Opcode als Integer-Konstante, z. B. ZEND_NEW, ZEND_EXIT oder ZEND_FETCH_OBJ. Die verfügbaren Opcode-Konstanten sind in der UOPZ-Extension definiert.
$handler Pflicht callable|null Ein PHP-Callable, das anstelle des originalen Opcodes aufgerufen wird. Die erwartete Signatur des Handlers hängt vom jeweiligen Opcode ab. Wird null übergeben, wird ein zuvor gesetzter Overload entfernt und der originale Opcode wiederhergestellt.

Rückgabewert

Typ
void
Beschreibung
Die Funktion hat keinen Rückgabewert.

Beispiele

exit/die im Unit-Test abfangen

<?php
// UOPZ-Extension (Version < 5.x) wird benötigt
// Verhindert, dass exit() den PHP-Prozess beendet

uopz_overload(ZEND_EXIT, function() {
    // exit-Aufruf wurde abgefangen — hier kann z. B. eine Exception geworfen werden
    throw new RuntimeException('exit() wurde aufgerufen, aber durch UOPZ abgefangen.');
});

try {
    exit(1); // Wird NICHT den Prozess beenden
} catch (RuntimeException $e) {
    echo 'Abgefangen: ' . $e->getMessage() . PHP_EOL;
}

// Overload wieder entfernen
uopz_overload(ZEND_EXIT, null);
Abgefangen: exit() wurde aufgerufen, aber durch UOPZ abgefangen.

Instanziierungen mit ZEND_NEW überwachen

<?php
// Jeden new-Aufruf protokollieren
$log = [];

uopz_overload(ZEND_NEW, function(string $className) use (&$log) {
    $log[] = 'Instanziiert: ' . $className;
    // Kein Rückgabewert => originales Verhalten wird fortgesetzt
});

$pdo  = new stdClass();
$dt   = new DateTime();

uopz_overload(ZEND_NEW, null);

foreach ($log as $entry) {
    echo $entry . PHP_EOL;
}
Instanziiert: stdClass Instanziiert: DateTime

// Wichtig · Fallstricke

Deprecation / Entfernung: uopz_overload() wurde in UOPZ ab Version 5.0 entfernt. Für aktuelle UOPZ-Versionen stehen spezifischere Funktionen zur Verfügung, wie uopz_set_return(), uopz_add_function() oder uopz_set_mock().

Produktiveinsatz: Diese Funktion ist ausschließlich für Test- und Debugging-Zwecke gedacht. Der Einsatz in produktivem Code ist gefährlich, da das Überladen von VM-Opcodes das gesamte Laufzeitverhalten von PHP für den aktuellen Prozess verändert und schwer nachvollziehbare Seiteneffekte erzeugen kann.

Stabilität: Da die Funktion direkt in die Zend-VM eingreift, kann fehlerhafter Gebrauch zu Crashes, Memory-Corruption oder undefiniertem Verhalten führen.