Signatur
Beschreibung
fsockopen() stellt eine Netzwerkverbindung zu einem entfernten Host her und gibt eine Stream-Ressource zurück. Diese Ressource kann mit den üblichen Datei-Funktionen wie fgets(), fwrite(), fread() und fclose() verwendet werden. Typische Anwendungsfälle sind einfache HTTP-Anfragen, SMTP-Kommunikation oder eigene TCP-Protokolle, wenn die höherwertigen Wrapper (z. B. cURL oder PHP-Streams) nicht genutzt werden sollen.
Der $hostname-Parameter unterstützt verschiedene Präfixe: tcp://, udp:// für UDP-Verbindungen, unix:// für Unix-Domain-Sockets sowie ssl:// und tls:// für verschlüsselte Verbindungen (sofern OpenSSL aktiviert ist). Wird kein Präfix angegeben, wird TCP verwendet.
Der Verbindungsaufbau ist standardmäßig blockierend. Mit stream_set_blocking() oder stream_set_timeout() kann das Verhalten der Ressource nachträglich angepasst werden. Für nicht-blockierende Verbindungsversuche existiert pfsockopen() als persistente Variante.
Bei einem Fehler gibt die Funktion false zurück und befüllt die optionalen Parameter $error_code und $error_message mit Informationen zum aufgetretenen Problem, was eine gezielte Fehlerbehandlung ermöglicht.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $hostname Pflicht | string | Hostname oder IP-Adresse des Zielservers. Optionale Präfixe wie tcp://, udp://, ssl://, tls:// oder unix:// steuern das verwendete Protokoll. |
|
| $port | int | -1 | Port-Nummer des Zieldienstes (z. B. 80 für HTTP, 443 für HTTPS). Bei Unix-Domain-Sockets muss -1 übergeben werden. |
| $error_code | int | null | Wird im Fehlerfall mit dem numerischen System-Fehlercode befüllt. Bei einem Fehler vor dem eigentlichen Verbindungsaufbau kann der Wert 0 sein. |
| $error_message | string | null | Wird im Fehlerfall mit einer menschenlesbaren Fehlermeldung befüllt, die den Grund des Verbindungsfehlers beschreibt. |
| $timeout | float | ini_get('default_socket_timeout') | Timeout in Sekunden für den Verbindungsaufbau. Dieser Wert gilt nur für die Verbindungsphase; Lese-/Schreiboperationen auf dem Stream sind davon unabhängig. |
Rückgabewert
false zurückgegeben und $error_code sowie $error_message werden gesetzt.Beispiele
Einfache HTTP-GET-Anfrage über fsockopen
<?php
$host = 'www.example.com';
$port = 80;
$errno = 0;
$errstr = '';
$timeout = 5.0;
$socket = fsockopen($host, $port, $errno, $errstr, $timeout);
if ($socket === false) {
echo "Verbindung fehlgeschlagen: [{$errno}] {$errstr}\n";
exit;
}
// HTTP-Anfrage senden
$request = "GET / HTTP/1.1\r\n";
$request .= "Host: {$host}\r\n";
$request .= "Connection: Close\r\n\r\n";
fwrite($socket, $request);
// Antwort lesen
$response = '';
while (!feof($socket)) {
$response .= fgets($socket, 1024);
}
fclose($socket);
// Nur den HTTP-Status ausgeben
$statusLine = strtok($response, "\n");
echo $statusLine . "\n";
Verschlüsselte Verbindung (HTTPS) mit ssl://
<?php
$host = 'www.example.com';
$port = 443;
$errno = 0;
$errstr = '';
$timeout = 10.0;
$socket = fsockopen('ssl://' . $host, $port, $errno, $errstr, $timeout);
if ($socket === false) {
echo "SSL-Verbindung fehlgeschlagen: [{$errno}] {$errstr}\n";
exit;
}
fwrite($socket, "GET / HTTP/1.1\r\nHost: {$host}\r\nConnection: Close\r\n\r\n");
$response = '';
while (!feof($socket)) {
$response .= fgets($socket, 4096);
}
fclose($socket);
// HTTP-Statuszeile extrahieren
preg_match('/^HTTP\/\d\.\d (\d{3} .+)/m', $response, $matches);
echo isset($matches[1]) ? $matches[1] . "\n" : "Kein Status gefunden\n";
Fehlerbehandlung bei nicht erreichbarem Host
<?php
$errno = 0;
$errstr = '';
$socket = @fsockopen('nicht-vorhanden.example.invalid', 80, $errno, $errstr, 3.0);
if ($socket === false) {
echo "Fehler-Code: {$errno}\n";
echo "Fehler-Text: {$errstr}\n";
} else {
fclose($socket);
}
// Wichtig · Fallstricke
Sicherheit: Wird der $hostname-Parameter aus Benutzereingaben übernommen, muss er unbedingt validiert werden. Andernfalls kann ein Angreifer den Server als Proxy missbrauchen (Server-Side Request Forgery, SSRF), um interne Dienste im Netzwerk anzusprechen.
SSL/TLS: Bei der Verwendung von ssl:// prüft PHP das Zertifikat des Servers standardmäßig. In älteren PHP-Versionen oder bei selbst signierten Zertifikaten mussten Stream-Kontextoptionen gesetzt werden, um die Prüfung anzupassen — aus Sicherheitsgründen sollte die Verifizierung jedoch niemals deaktiviert werden.
Timeout-Verhalten: Der $timeout-Parameter steuert ausschließlich den Verbindungsaufbau. Um einen Timeout für nachfolgende Lese-/Schreiboperationen zu setzen, muss stream_set_timeout() nach dem Verbindungsaufbau aufgerufen werden.
Empfehlung: Für komplexe HTTP-Anfragen empfiehlt sich die Verwendung von cURL (curl_init()) oder PHP-Streams mit file_get_contents() und einem Stream-Kontext, da diese vollständige Protokoll-Unterstützung, Redirect-Handling und bessere Fehlerbehandlung bieten.