Signatur
Beschreibung
stream_set_timeout() legt fest, wie lange PHP maximal auf eine Antwort eines Streams wartet, bevor eine Operation als fehlgeschlagen gilt. Dies ist besonders nützlich bei Netzwerk-Streams (z. B. TCP-Verbindungen via fsockopen() oder stream_socket_client()), um zu verhindern, dass das Skript unendlich lang blockiert wird.
Der Timeout-Wert wird als Kombination aus ganzen Sekunden ($seconds) und Mikrosekunden ($microseconds) angegeben. Nach Ablauf des Timeouts schlägt die nächste Lese-/Schreiboperation auf dem Stream nicht unmittelbar mit einem Fehler fehl, aber stream_get_meta_data() meldet im Schlüssel timed_out den Wert true.
Typische Anwendungsfälle sind HTTP-Clients, SMTP-Verbindungen, Datenbank-Sockets oder jede andere Art von Netzwerkkommunikation, bei der ein hängendes Remote-Ende das Skript nicht dauerhaft blockieren soll. Der gesetzt Timeout gilt pro Lese-/Schreiboperation, nicht für die gesamte Verbindung.
Wichtig: Diese Funktion hat keinen Einfluss auf dateibasierte Streams (z. B. lokale Dateien), da diese kein echtes Blocking kennen. Sie wirkt nur bei Streams, die tatsächlich blockieren können.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $stream Pflicht | resource | Eine gültige Stream-Ressource, z. B. von fsockopen(), fopen() oder stream_socket_client(). |
|
| $seconds Pflicht | int | Der ganzzahlige Anteil des Timeouts in Sekunden. Muss 0 oder positiv sein. |
|
| $microseconds | int | 0 | Zusätzlicher Anteil des Timeouts in Mikrosekunden (1 Sekunde = 1.000.000 Mikrosekunden). Erlaubt eine feinere Einstellung unterhalb einer ganzen Sekunde. |
Rückgabewert
true bei Erfolg zurück, false wenn der Timeout nicht gesetzt werden konnte (z. B. bei einer ungültigen Stream-Ressource).Beispiele
Timeout für eine TCP-Verbindung setzen
<?php
// Verbindung zu einem HTTP-Server aufbauen
$stream = fsockopen('example.com', 80, $errno, $errstr, 10);
if (!$stream) {
echo "Verbindungsfehler: $errstr ($errno)\n";
exit;
}
// Timeout auf 5 Sekunden für Lese-/Schreiboperationen setzen
stream_set_timeout($stream, 5);
// HTTP-Request senden
fwrite($stream, "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n");
// Antwort lesen
$response = fread($stream, 1024);
// Prüfen ob ein Timeout aufgetreten ist
$info = stream_get_meta_data($stream);
if ($info['timed_out']) {
echo "Stream-Timeout: Die Verbindung hat zu lange nicht geantwortet.\n";
} else {
echo "Antwort erhalten (erste 100 Zeichen):\n";
echo substr($response, 0, 100) . "\n";
}
fclose($stream);
Feinen Timeout unter einer Sekunde mit Mikrosekunden
<?php
// Socket-Verbindung mit 500 Millisekunden (= 500.000 Mikrosekunden) Timeout
$stream = stream_socket_client('tcp://example.com:80', $errno, $errstr, 5);
if (!$stream) {
echo "Verbindungsfehler: $errstr ($errno)\n";
exit;
}
// Timeout auf 0 Sekunden + 500.000 Mikrosekunden = 0,5 Sekunden
$result = stream_set_timeout($stream, 0, 500000);
if ($result) {
echo "Timeout erfolgreich auf 500 ms gesetzt.\n";
} else {
echo "Timeout konnte nicht gesetzt werden.\n";
}
fwrite($stream, "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n");
$data = '';
while (!feof($stream)) {
$chunk = fread($stream, 1024);
$meta = stream_get_meta_data($stream);
if ($meta['timed_out']) {
echo "Timeout beim Lesen aufgetreten!\n";
break;
}
$data .= $chunk;
}
echo "Empfangene Bytes: " . strlen($data) . "\n";
fclose($stream);
// Wichtig · Fallstricke
Timeout-Erkennung: stream_set_timeout() selbst wirft keine Exception und gibt keinen Fehler aus, wenn der Timeout überschritten wird. Es muss nach jeder Lese-/Schreiboperation stream_get_meta_data() abgefragt werden, um den Schlüssel timed_out zu prüfen.
Kein Einfluss auf set_time_limit(): Der Stream-Timeout ist unabhängig vom PHP-Skript-Timeout (max_execution_time). Beide Limits können unabhängig voneinander greifen.
Kein Gesamt-Timeout: Der eingestellte Timeout gilt pro einzelner blockierender Operation (z. B. fread()), nicht für die Gesamtdauer der Verbindung. Bei mehreren aufeinanderfolgenden Leseoperationen kann der Gesamtzeitraum ein Vielfaches des eingestellten Timeouts betragen.
Datei-Streams: Bei lokalen Datei-Streams hat stream_set_timeout() in der Regel keine Wirkung, da lokale Dateioperationen normalerweise nicht blockieren.