Signatur
Beschreibung
Swoole\Runtime ermöglicht es, Standard-PHP-Funktionen wie sleep(), file_get_contents(), PDO, MySQLi, Redis und viele weitere blockierende Operationen automatisch in Koroutinen-kompatible, nicht-blockierende Varianten umzuwandeln – ohne den bestehenden Code anpassen zu müssen. Dies geschieht über den sogenannten Hook-Mechanismus, der intern die Zend-Engine-Hooks nutzt.
Die wichtigste Methode ist Swoole\Runtime::enableCoroutine(). Sie wird typischerweise einmalig am Anfang des Programms aufgerufen, bevor der Swoole-Server startet, oder innerhalb eines Koroutinen-Kontexts. Mit dem Parameter $flags kann feingranular gesteuert werden, welche PHP-Erweiterungen und Funktionen gehooked werden sollen (z. B. nur Sleep, nur Streams oder alle unterstützten Funktionen).
Ohne diesen Mechanismus würden blockierende PHP-Funktionen den gesamten Swoole-Worker-Prozess blockieren und so die Vorteile der asynchronen Programmierung zunichte machen. Durch das Aktivieren der Runtime-Hooks werden solche Aufrufe stattdessen innerhalb der Koroutinen-Scheduler-Schleife aufgelöst, sodass andere Koroutinen während des Wartens weiterlaufen können.
Typische Anwendungsfälle sind die Migration bestehender synchroner PHP-Anwendungen auf Swoole sowie die Nutzung bekannter Bibliotheken (z. B. PDO, Guzzle mit Stream-Adaptern) innerhalb von Swoole-Koroutinen ohne Code-Änderungen.
Beispiele
Alle Hooks aktivieren und parallele HTTP-Anfragen stellen
<?php
// Alle unterstützten PHP-Funktionen für Koroutinen-Hooks aktivieren
Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
Swoole\Coroutine\run(function () {
// Beide file_get_contents()-Aufrufe laufen parallel (nicht-blockierend)
$results = [];
$wg = new Swoole\Coroutine\WaitGroup();
$wg->add();
Swoole\Coroutine::create(function () use (&$results, $wg) {
$results['php'] = file_get_contents('https://www.php.net');
$wg->done();
});
$wg->add();
Swoole\Coroutine::create(function () use (&$results, $wg) {
$results['swoole'] = file_get_contents('https://www.swoole.com');
$wg->done();
});
$wg->wait();
echo 'PHP-Seite Länge: ' . strlen($results['php']) . PHP_EOL;
echo 'Swoole-Seite Länge: ' . strlen($results['swoole']) . PHP_EOL;
});
Nur bestimmte Hooks aktivieren und PDO in Koroutine nutzen
<?php
// Nur Hooks für Sockets und Sleep aktivieren
Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_TCP | SWOOLE_HOOK_SLEEP);
$http = new Swoole\HTTP\Server('0.0.0.0', 9501);
$http->on('workerStart', function () {
// PDO-Hook separat aktivieren
Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_PDO_PGSQL);
});
$http->on('request', function ($request, $response) {
Swoole\Coroutine::create(function () use ($response) {
// Normaler PDO-Code läuft jetzt nicht-blockierend
$pdo = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', '');
$stmt = $pdo->query('SELECT 1 + 1 AS result');
$row = $stmt->fetch();
$response->end('Ergebnis: ' . $row['result']);
});
});
$http->start();
Hook-Status prüfen und deaktivieren
<?php
// Hooks aktivieren
Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
echo 'Hooks aktiv: ' . (Swoole\Runtime::isHookEnabled() ? 'ja' : 'nein') . PHP_EOL;
// Hooks bei Bedarf wieder deaktivieren
Swoole\Runtime::enableCoroutine(false);
echo 'Hooks aktiv: ' . (Swoole\Runtime::isHookEnabled() ? 'ja' : 'nein') . PHP_EOL;
// Wichtig · Fallstricke
Wichtiger Hinweis zur Aktivierungsreihenfolge: Swoole\Runtime::enableCoroutine() sollte vor dem Start des Servers oder vor dem Erstellen von Koroutinen aufgerufen werden. Ein nachträgliches Aktivieren innerhalb bereits laufender Koroutinen kann zu unvorhersehbarem Verhalten führen.
- Nicht alle PHP-Erweiterungen werden unterstützt. Erweiterungen wie
ext-curlwerden überSWOOLE_HOOK_CURLgehooked, benötigen aber Swoole ≥ 4.6.0. Prüfe die Swoole-Dokumentation für die aktuelle Kompatibilitätsliste. - Flags: Die Konstante
SWOOLE_HOOK_ALLaktiviert alle verfügbaren Hooks. Einzelne Hooks können per Bitmaske kombiniert werden (z. B.SWOOLE_HOOK_SLEEP | SWOOLE_HOOK_FILE), um den Overhead zu minimieren. - Kompatibilität: Einige ältere PHP-Bibliotheken, die Low-Level-Ressource-Handles direkt manipulieren, könnten mit aktivierten Hooks inkompatibel sein. In diesem Fall nur gezielt benötigte Hooks aktivieren.
- Koroutinen-Kontext erforderlich: Die Hooks wirken nur innerhalb eines aktiven Koroutinen-Kontexts (z. B. innerhalb von
Swoole\Coroutine\run()). Außerhalb davon verhalten sich die Funktionen wie gewohnt synchron.