PHP socket_get_status() Funktion: Alles, was Sie wissen müssen
Die PHP-Funktion socket_get_status() gibt den aktuellen Status eines Stream-Resources als assoziatives Array zurück.
Wenn Sie in PHP von einer Netzwerkverbindung lesen oder in sie schreiben, müssen Sie oft wissen, ob die Verbindung noch aktiv ist, ob ein Lesevorgang eine Zeitüberschreitung hatte oder wie viele Bytes im Puffer warten. Die Funktion socket_get_status() beantwortet genau diese Fragen: Sie gibt einen Schnappschuss des aktuellen Zustands eines Streams zurück.
Dieses Kapitel erklärt, was socket_get_status() zurückgibt, wann jedes Feld wichtig ist und wie man es sicher mit Timeouts und nicht-blockierenden Streams verwendet.
Was ist die socket_get_status() Funktion?
socket_get_status() ruft den aktuellen Status einer Stream-Resource als assoziatives Array ab. Sie ist eigentlich ein Alias von stream_get_meta_data(), sodass beide dieselben Daten zurückgeben — socket_get_status() ist lediglich der historische Name, der für Netzwerkcode beibehalten wird.
Trotz des Namens ist die Funktion für Stream-Resources konzipiert — die Art, die von fsockopen(), pfsockopen() oder stream_socket_client() zurückgegeben werden — und nicht für die Low-Level-Socket-Resources, die von socket_create() erstellt werden. Das Übergeben des falschen Resource-Typs kann in PHP 8+ Deprecation-Warnungen auslösen und liefert nicht die erwarteten Daten.
Wie verwendet man die socket_get_status() Funktion?
Die Verwendung der Funktion socket_get_status() ist unkompliziert. Hier ist die Syntax der Funktion:
Die PHP-Syntax der socket_get_status() Funktion
socket_get_status(resource $stream): arrayDie Funktion nimmt einen Parameter entgegen:
$stream: Die Stream-Resource, deren Status abgerufen werden soll.
Sie gibt ein assoziatives Array zurück. Die nützlichsten Schlüssel sind:
| Schlüssel | Typ | Bedeutung |
|---|---|---|
timed_out | bool | true, wenn der letzte Lese-/Schreibvorgang den Stream-Timeout überschritten hat. |
blocked | bool | true, wenn sich der Stream im Blocking-Modus befindet. |
eof | bool | true, wenn das Ende des Streams erreicht wurde (Verbindung geschlossen). |
unread_bytes | int | Bytes, die bereits in PHPs internen Puffer gelesen, aber noch nicht verarbeitet wurden. |
stream_type | string | Der zugrunde liegende Transport, z. B. tcp_socket/ssl. |
wrapper_type | string | Der Wrapper, der den Stream verarbeitet, z. B. http. |
mode | string | Der Zugriffsmodus, mit dem der Stream geöffnet wurde, z. B. r+. |
Prüfen, ob eine Verbindung noch offen ist
Hier ist ein minimales Beispiel, das einen TCP-Stream öffnet, eine Zeile liest und socket_get_status() verwendet, um festzustellen, ob der Server die Verbindung geschlossen hat:
Wie verwendet man die socket_get_status() Funktion?
<?php
$stream = fsockopen("tcp://www.example.com", 80, $errno, $errstr, 30);
if (!$stream) {
die("Error: $errstr ($errno)");
}
fwrite($stream, "GET / HTTP/1.0\r\nHost: www.example.com\r\n\r\n");
$line = fgets($stream);
$status = socket_get_status($stream);
echo $status["eof"] ? "Connection closed by server\n" : "Connection still open\n";
fclose($stream);
?>Wir verwenden fsockopen(), um einen Stream zu erstellen, und prüfen, ob er erfolgreich erstellt wurde, bevor wir weitermachen. Nach dem Senden einer Anfrage und dem Lesen einer Zeile mit fgets() zeigt das Feld eof, ob die Gegenseite fertig ist. Schließen Sie den Stream immer mit fclose(), wenn Sie fertig sind.
Erkennen eines Lese-Timeouts
Das Feld timed_out ist es, was socket_get_status() wirklich nützlich macht. Wenn Sie ein Lese-Timeout mit stream_set_timeout() (oder socket_set_timeout()) setzen, wirft ein langsamer Lesevorgang keine Ausnahme — fgets() gibt einfach false zurück. Dann rufen Sie socket_get_status() auf, um herauszufinden, warum es false zurückgegeben hat:
<?php
$stream = fsockopen("tcp://www.example.com", 80, $errno, $errstr, 30);
if (!$stream) {
die("Error: $errstr ($errno)");
}
// Wait at most 2 seconds for data before giving up.
stream_set_timeout($stream, 2);
$line = fgets($stream); // We never sent a request, so nothing arrives.
$status = socket_get_status($stream);
if ($status["timed_out"]) {
echo "Read timed out\n";
} else {
echo "Got data\n";
}
fclose($stream);
?>Da keine Anfrage gesendet wurde, hat der Server nichts zu antworten, der 2-Sekunden-Timeout läuft ab und das Skript gibt Read timed out aus. Ohne socket_get_status() könnten Sie einen Timeout nicht von einem echten Stream-Ende unterscheiden — beide lassen fgets() false zurückgeben.
Wann sollte man socket_get_status() verwenden?
- Nach einem fehlgeschlagenen Lesevorgang.
fgets()/fread(), diefalsezurückgeben, sind mehrdeutig; prüfen Sietimed_outundeof, um zu erfahren, was passiert ist. - Vor dem Wiederverwenden einer Verbindung. Prüfen Sie
eof, um zu bestätigen, dass ein Keep-Alive-Socket noch aktiv ist, bevor Sie eine weitere Anfrage senden. - Mit nicht-blockierenden Streams. Wenn Sie
stream_set_blocking()aufrufen, um einen Socket nicht-blockierend zu machen, helfenunread_bytesundblockedbei der Analyse gepufferter Daten.
Fallstricke
- Es funktioniert nur bei Stream-Resources — nicht bei
socket_create()-Resources. Verwenden Sie dafür stattdessensocket_last_error()/socket_get_option(). socket_get_status()spiegelt den Puffer- und Timeout-Zustand zum Zeitpunkt des Aufrufs wider; die Funktion untersucht das Netzwerk nicht aktiv, daher ist eineof-Wert vonfalsekeine Garantie, dass die Gegenseite noch erreichbar ist.- Setzen Sie das Timeout-Flag zurück, indem Sie einen weiteren erfolgreichen Lesevorgang durchführen — das Array wird bei jedem Aufruf neu berechnet.
Fazit
Die Funktion socket_get_status() ist eine schlanke Möglichkeit, den Zustand eines Stream-Sockets in PHP zu untersuchen. Ihr wertvollstes Feld ist timed_out, mit dem Sie einen Lese-Timeout von einer geschlossenen Verbindung unterscheiden können — etwas, das der Rückgabewert von fgets() allein nicht leisten kann. In Kombination mit eof, unread_bytes und den Timeout- und Blocking-Steuerungsfunktionen von stream_set_timeout() und stream_set_blocking() liefert sie die Informationen, die Sie benötigen, um Netzwerkverbindungen zuverlässig zu verwalten.