Signatur
Beschreibung
stream_socket_client() stellt eine Socket-Verbindung zu einem angegebenen Ziel her und gibt eine Stream-Ressource zurück, die mit den üblichen Stream-Funktionen wie fread(), fwrite() und fclose() verwendet werden kann. Die Adresse kann verschiedene Transport-Protokolle nutzen, z. B. tcp://, udp://, ssl://, tls:// oder unix://.
Über den Parameter $flags lässt sich steuern, ob die Verbindung synchron (STREAM_CLIENT_CONNECT), asynchron (STREAM_CLIENT_ASYNC_CONNECT) oder persistent (STREAM_CLIENT_PERSISTENT) aufgebaut wird. Persistente Verbindungen werden über mehrere Requests hinweg wiederverwendet und verbessern die Performance bei häufigen Verbindungen zum gleichen Ziel.
Schlägt der Verbindungsaufbau fehl, wird false zurückgegeben. Die Fehlerursache kann dann über die per Referenz übergebenen Parameter $error_code und $error_message ausgelesen werden. Ein optionaler Stream-Kontext ($context) erlaubt die feingranulare Steuerung von TLS-Optionen, Proxy-Einstellungen und mehr.
Typische Einsatzgebiete sind das direkte Ansprechen von TCP/UDP-Diensten, die Implementierung von HTTP-Clients ohne cURL, der Aufbau verschlüsselter TLS-Verbindungen sowie die Kommunikation über Unix-Domain-Sockets bei lokalen Diensten.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $address Pflicht | string | Die Zieladresse im Format transport://host:port, z. B. tcp://example.com:80, ssl://example.com:443 oder unix:///var/run/service.sock. |
|
| $error_code | int | null | Wird per Referenz übergeben und enthält nach einem Fehler den systemspezifischen Fehlercode (entspricht dem POSIX-Fehler). |
| $error_message | string | null | Wird per Referenz übergeben und enthält nach einem Fehler eine lesbare Fehlermeldung als Zeichenkette. |
| $timeout | float | ini_get("default_socket_timeout") | Timeout in Sekunden für den Verbindungsaufbau. Wird kein Wert übergeben, gilt der PHP-INI-Wert default_socket_timeout. |
| $flags | int | STREAM_CLIENT_CONNECT | Bitmaske aus Verbindungsflags: STREAM_CLIENT_CONNECT (synchron), STREAM_CLIENT_ASYNC_CONNECT (asynchron) oder STREAM_CLIENT_PERSISTENT (persistente Verbindung). |
| $context | resource | null | Ein mit stream_context_create() erzeugter Stream-Kontext, über den z. B. TLS-Zertifikate, Proxy-Server oder weitere Optionen konfiguriert werden können. |
Rückgabewert
false zurückgegeben und die Fehlerinformationen stehen in $error_code und $error_message zur Verfügung.Beispiele
Einfache TCP-Verbindung zu einem HTTP-Server
<?php
$errno = 0;
$errstr = '';
$socket = stream_socket_client(
'tcp://example.com:80',
$errno,
$errstr,
5.0
);
if ($socket === false) {
echo "Verbindungsfehler [{$errno}]: {$errstr}\n";
exit(1);
}
// HTTP-Anfrage senden
fwrite($socket, "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n");
// Antwort lesen
$response = '';
while (!feof($socket)) {
$response .= fread($socket, 8192);
}
fclose($socket);
// Ersten 200 Zeichen der Antwort ausgeben
echo substr($response, 0, 200);
Verschlüsselte TLS-Verbindung mit Kontext-Optionen
<?php
$context = stream_context_create([
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
'cafile' => '/etc/ssl/certs/ca-certificates.crt',
'SNI_enabled' => true,
],
]);
$errno = 0;
$errstr = '';
$socket = stream_socket_client(
'tls://example.com:443',
$errno,
$errstr,
10.0,
STREAM_CLIENT_CONNECT,
$context
);
if ($socket === false) {
echo "TLS-Verbindungsfehler [{$errno}]: {$errstr}\n";
exit(1);
}
fwrite($socket, "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n");
$response = stream_get_contents($socket);
fclose($socket);
echo "Statuszeile: " . strtok($response, "\r\n") . "\n";
Persistente Verbindung für Wiederverwendung
<?php
function getSocket(string $host, int $port): resource
{
$errno = 0;
$errstr = '';
$socket = stream_socket_client(
"tcp://{$host}:{$port}",
$errno,
$errstr,
5.0,
STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT
);
if ($socket === false) {
throw new RuntimeException("Verbindung fehlgeschlagen [{$errno}]: {$errstr}");
}
return $socket;
}
// Persistente Verbindung – beim zweiten Aufruf wird die bestehende Verbindung wiederverwendet
$sock1 = getSocket('127.0.0.1', 6379);
$sock2 = getSocket('127.0.0.1', 6379);
var_dump($sock1 === $sock2); // true bei persistenter Verbindung
fclose($sock1);
// Wichtig · Fallstricke
Sicherheit: Bei TLS-Verbindungen sollte verify_peer und verify_peer_name im Stream-Kontext stets auf true gesetzt sein, da PHP sie standardmäßig aktiviert. Das Deaktivieren dieser Optionen macht die Verbindung anfällig für Man-in-the-Middle-Angriffe.
Timeout-Verhalten: Der $timeout-Parameter gilt nur für den Verbindungsaufbau, nicht für nachfolgende Lese-/Schreiboperationen. Für den Datentransfer-Timeout muss stream_set_timeout() nach dem Verbindungsaufbau aufgerufen werden.
Nicht-blockierender Modus: Mit stream_set_blocking($socket, false) kann der Stream in den nicht-blockierenden Modus versetzt werden, was bei asynchronen Szenarien oder der Überwachung mehrerer Sockets mit stream_select() nützlich ist.
Persistente Verbindungen: Persistente Verbindungen (STREAM_CLIENT_PERSISTENT) bleiben nach fclose() intern erhalten und werden beim nächsten Aufruf mit derselben Adresse wiederverwendet. Dies kann zu unerwartetem Verhalten führen, wenn der entfernte Server die Verbindung getrennt hat.