W3docs

PHP socket_set_timeout() Funktion: Alles, was Sie wissen müssen

Erfahren Sie, wie socket_set_timeout() in PHP Timeouts für Streams setzt, häufige Fallstricke vermeidet und wie Sie Timeouts zuverlässig erkennen.

Wenn Ihr Skript von einer Netzwerkverbindung liest, kann ein langsamer oder ausgefallener Server PHP auf unbestimmte Zeit blockieren, einen Worker belegen und Benutzer frustrieren. Die Funktion socket_set_timeout() setzt eine Frist für Lese- und Schreiboperationen, sodass eine blockierte Verbindung schnell scheitert, anstatt zu hängen. Dieser Artikel erklärt genau, was sie steuert, die häufigsten Fallstricke und wie Sie einen Timeout erkennen, wenn er auftritt.

Was die Funktion socket_set_timeout() tut

socket_set_timeout() legt den Timeout für I/O-Operationen fest — fread(), fgets(), fwrite() usw. — auf einem Stream, der mit fsockopen() oder pfsockopen() geöffnet wurde. Wenn ein Lese- oder Schreibvorgang nicht innerhalb der Frist abgeschlossen wird, gibt die Operation frühzeitig zurück und der Stream wird als timed out markiert.

Zwei Dinge tut sie nicht:

  • Sie beeinflusst nicht den Verbindungs-Timeout. Das ist das fünfte Argument von fsockopen($host, $port, $errno, $errstr, $connectTimeout). socket_set_timeout() regelt nur die Datenübertragung, nachdem die Verbindung hergestellt ist.
  • Sie lässt den Aufruf nicht laut scheitern. Ein Lesevorgang, der einen Timeout erreicht, gibt die bisher empfangenen Daten zurück (oft ein leerer string) und setzt ein Flag — Sie müssen dieses Flag selbst mit stream_get_meta_data() prüfen.

Namens-Falle: Trotz des socket_-Präfixes gehört diese Funktion zur Streams-Familie und nicht zur Sockets-Erweiterung. Sie funktioniert mit Ressourcen aus fsockopen(), niemals mit einer Ressource aus socket_create(). Seit PHP 8.0 ist sie ein veralteter Alias von stream_set_timeout() — bevorzugen Sie diesen Namen in neuem Code.

Syntax

socket_set_timeout(resource $stream, int $seconds, int $microseconds = 0): bool
ParameterBeschreibung
$streamEine offene Stream-Ressource, die von fsockopen() oder pfsockopen() zurückgegeben wird.
$secondsDer Timeout in ganzen Sekunden.
$microsecondsZusätzliche Zeit in Mikrosekunden (optional, Standard 0).

Die Funktion gibt true bei Erfolg und false bei Fehler zurück (zum Beispiel wenn $stream keine gültige Stream-Ressource ist).

Ein funktionierendes Beispiel

Öffnen Sie eine Verbindung, setzen Sie einen 5-Sekunden-Lese-Timeout und prüfen Sie dann, ob ein Lesevorgang einen Timeout hatte:

<?php

// Open a TCP connection to a web server.
$stream = fsockopen("www.example.com", 80, $errno, $errstr, 10);

if (!$stream) {
    echo "Connection failed: $errstr ($errno)\n";
    exit;
}

// Fail any single read/write that stalls for more than 5 seconds.
socket_set_timeout($stream, 5);

// Send a minimal HTTP request.
fwrite($stream, "GET / HTTP/1.0\r\nHost: www.example.com\r\n\r\n");

// Read the first line of the response.
$line = fgets($stream, 1024);

// Check whether that read hit the timeout.
$info = stream_get_meta_data($stream);

if ($info['timed_out']) {
    echo "Read timed out — the server was too slow.\n";
} else {
    echo "First response line: " . trim($line) . "\n";
}

fclose($stream);

Der Schlüssel ist der stream_get_meta_data()-Aufruf: Sein Element timed_out ist der einzige zuverlässige Weg, einen echten Timeout von einer Verbindung zu unterscheiden, die einfach geschlossen wurde.

Lesen in einer Schleife

Wenn Sie eine vollständige Antwort lesen, prüfen Sie bei jeder Iteration timed_out, damit ein Stillstand mitten in der Übertragung Ihre Daten nicht stillschweigend abschneidet:

<?php

$stream = fsockopen("www.example.com", 80, $errno, $errstr, 10);
socket_set_timeout($stream, 5);

fwrite($stream, "GET / HTTP/1.0\r\nHost: www.example.com\r\n\r\n");

$body = "";
while (!feof($stream)) {
    $chunk = fgets($stream, 4096);
    $info  = stream_get_meta_data($stream);

    if ($info['timed_out']) {
        echo "Stalled before the response finished.\n";
        break;
    }
    $body .= $chunk;
}

fclose($stream);
echo "Received " . strlen($body) . " bytes.\n";

Häufige Fallstricke

  • Falscher Ressourcentyp. Eine socket_create()-Ressource zu übergeben bewirkt nichts Nützliches — verwenden Sie stream_set_timeout() mit socket_create()-Sockets oder socket_set_option() für SO_RCVTIMEO/SO_SNDTIMEO.
  • Verbindungs- und Lese-Timeout verwechseln. Ein langer fsockopen()-Verbindungs-Timeout schützt Sie nicht vor einer langsamen Antwort; Sie benötigen beides.
  • Vergessen, timed_out zu prüfen. Ohne diese Prüfung sieht ein Lese-Timeout genauso aus wie ein normales Ende des Streams, was zu stillschweigend abgeschnittenen Daten führt.

Verwandte Funktionen

Fazit

socket_set_timeout() verhindert, dass langsame Netzwerk-Lese- und Schreibvorgänge Ihr PHP-Skript blockieren. Denken Sie daran, dass sie auf fsockopen()-Streams (nicht auf die Sockets-Erweiterung) wirkt, I/O statt der Verbindung regelt und dass Sie das timed_out-Flag von stream_get_meta_data() prüfen müssen, um zu wissen, ob tatsächlich ein Timeout aufgetreten ist. Verwenden Sie in neuem Code den modernen Namen stream_set_timeout().

Übungen

Übung
Was macht die Funktion socket_set_timeout() in PHP?
Was macht die Funktion socket_set_timeout() in PHP?
Was this page helpful?