Start · Sprachen · PHP · Referenz · swoole_select

swoole_select

Funktion

Überwacht in der Swoole-Event-Loop eine Menge von Dateideskriptoren auf Lese-, Schreib- oder Fehlerbereitschaft – ähnlich wie <code>stream_select()</code>, aber Swoole-nativ.

Kategorie: misc

Signatur

swoole_select(array &$read, array &$write, array &$error, float|null $timeout = null): int|false

Beschreibung

swoole_select() ist das Swoole-Äquivalent zur klassischen POSIX-select()-Funktion. Sie prüft gleichzeitig mehrere Dateideskriptoren (Sockets, Streams) darauf, ob sie zum Lesen ($read), Schreiben ($write) bereit sind oder ein Ausnahmezustand ($error) vorliegt. Die Funktion blockiert maximal für die angegebene Zeitspanne ($timeout) und kehrt zurück, sobald mindestens ein Deskriptor bereit ist oder der Timeout abgelaufen ist.

Im Gegensatz zu PHPs stream_select() ist swoole_select() auf die Swoole-Laufzeitumgebung abgestimmt und kann innerhalb von Swoole-Coroutinen und Event-Loop-Kontexten eingesetzt werden, ohne den gesamten Event-Loop zu blockieren. Dies macht sie nützlich, wenn mehrere Netzwerkressourcen gleichzeitig überwacht werden sollen.

Die Arrays $read, $write und $error werden als Referenz übergeben und nach dem Aufruf so modifiziert, dass sie nur noch die tatsächlich bereiten Deskriptoren enthalten. Nicht bereite Deskriptoren werden aus den Arrays entfernt.

Die Funktion eignet sich besonders für Szenarien, in denen mehrere TCP-Verbindungen oder Sockets parallel überwacht werden müssen, ohne für jede Verbindung einen eigenen Coroutine- oder Callback-Handler einzurichten.

Parameter

Name Typ Default Beschreibung
$read Pflicht array Array von Dateideskriptoren/Streams, die auf Lesebereitschaft überwacht werden sollen. Wird nach dem Aufruf auf die tatsächlich lesbereiten Deskriptoren reduziert.
$write Pflicht array Array von Dateideskriptoren/Streams, die auf Schreibbereitschaft überwacht werden sollen. Wird nach dem Aufruf auf die tatsächlich schreibbereiten Deskriptoren reduziert.
$error Pflicht array Array von Dateideskriptoren/Streams, die auf Ausnahmezustände (z. B. Out-of-Band-Daten) überwacht werden sollen. Wird nach dem Aufruf auf die Deskriptoren mit tatsächlichem Fehler reduziert.
$timeout float|null null Maximale Wartezeit in Sekunden (Dezimalzahlen erlaubt, z. B. 0.5 für 500 ms). null oder nicht angegeben bedeutet unbegrenztes Warten. 0 bewirkt einen sofortigen Nicht-blockierenden Check.

Rückgabewert

Typ
int|false
Beschreibung
Gibt die Gesamtanzahl der bereiten Dateideskriptoren (Summe aus $read, $write und $error) als Integer zurück. Gibt 0 zurück, wenn der Timeout abgelaufen ist, ohne dass ein Deskriptor bereit war. Gibt false im Fehlerfall zurück (z. B. ungültige Argumente oder interner Fehler).

Beispiele

Mehrere Sockets auf Lesebereitschaft prüfen

<?php
// Zwei nicht-blockierende TCP-Verbindungen öffnen
$sock1 = stream_socket_client('tcp://example.com:80', $errno, $errstr, 5);
$sock2 = stream_socket_client('tcp://example.org:80', $errno, $errstr, 5);

stream_set_blocking($sock1, false);
stream_set_blocking($sock2, false);

// HTTP-Anfrage senden
fwrite($sock1, "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n");
fwrite($sock2, "GET / HTTP/1.0\r\nHost: example.org\r\n\r\n");

$read  = [$sock1, $sock2];
$write = [];
$error = [];

// Bis zu 3 Sekunden warten
$ready = swoole_select($read, $write, $error, 3.0);

if ($ready === false) {
    echo "Fehler bei swoole_select\n";
} elseif ($ready === 0) {
    echo "Timeout – keine Antwort innerhalb von 3 Sekunden\n";
} else {
    foreach ($read as $sock) {
        echo "Daten verfügbar: " . fread($sock, 512) . "\n";
    }
}

fclose($sock1);
fclose($sock2);

Nicht-blockierender Check (Timeout = 0)

<?php
// Sofortigen Check ohne Warten durchführen
$sock = stream_socket_client('tcp://127.0.0.1:9501', $errno, $errstr, 1);
stream_set_blocking($sock, false);

$read  = [$sock];
$write = [];
$error = [];

// Timeout 0 = nicht blockieren, sofort zurückkehren
$ready = swoole_select($read, $write, $error, 0);

if ($ready > 0) {
    echo "Socket ist sofort lesbar: " . fread($sock, 256) . "\n";
} else {
    echo "Keine Daten sofort verfügbar.\n";
}

fclose($sock);
Keine Daten sofort verfügbar.

// Wichtig · Fallstricke

Swoole-Kontext erforderlich: swoole_select() ist nur verfügbar, wenn die Swoole-Extension installiert und aktiv ist. In reinen PHP-CLI- oder FPM-Umgebungen ohne Swoole steht die Funktion nicht zur Verfügung – dort sollte stattdessen stream_select() verwendet werden.

Vorsicht in Coroutinen: Der Einsatz in Swoole-Coroutinen kann den Event-Loop unter Umständen blockieren, wenn $timeout zu groß gewählt wird. Für coroutinefreundliche I/O-Operationen empfehlen sich die Swoole-Coroutine-Socket-APIs (Swoole\Coroutine\Socket).

Array-Mutation: Da $read, $write und $error als Referenz übergeben werden, sind die ursprünglichen Arrays nach dem Aufruf verändert. Wenn die ursprüngliche Deskriptoren-Liste erhalten bleiben soll, muss sie vorher kopiert werden.