Ce face fsockopen / pfsockopen
fsockopen se conectează la un server, după nume sau IP și port, și returnează un stream obișnuit. Pe el scrii cu fwrite și citești cu fgets sau fread, ca într-un fișier. Este cel mai simplu mod de a vorbi direct cu un server SMTP, Redis, un port de imprimantă sau un serviciu propriu.
Implicit, conexiunea este TCP. Pentru alt transport, pune-l în fața numelui: udp://, ssl://, tls://. La eșec, funcția returnează false, afișează un avertisment și pune codul și mesajul erorii în $error_code și $error_message.
pfsockopen are aceiași parametri, dar conexiunea este persistentă: nu se închide la finalul scriptului, ci este refolosită de cererile următoare servite de același proces PHP-FPM.
Parametri
| Parametru | Descriere |
|---|---|
$hostname |
Numele sau IP-ul serverului, opțional cu transport în față (ssl://smtp.exemplu.ro). |
$port |
Portul serverului. |
$error_code |
Opțional. Variabilă în care se pune codul erorii de sistem. |
$error_message |
Opțional. Variabilă în care se pune mesajul erorii. |
$timeout |
Opțional. Secundele de așteptare pentru conectare. Implicit default_socket_timeout (60). |
Ce returnează
Un stream conectat sau false dacă nu s-a putut conecta.
Exemple
Exemplul 1: Conversație cu un server local
Pornim în același script un server pe un port liber (portul 0 cere sistemului să aleagă unul). fsockopen se conectează la el, iar cele două capete își trimit câte o linie.
<?php
$server = stream_socket_server("tcp://127.0.0.1:0");
$port = (int) explode(":", stream_socket_get_name($server, false))[1];
$client = fsockopen("127.0.0.1", $port, $cod, $mesaj, 2);
$conexiune = stream_socket_accept($server);
fwrite($client, "Salut, server!\n");
echo "Serverul a primit: " . fgets($conexiune);
fwrite($conexiune, "Salut, Ana!\n");
echo "Clientul a primit: " . fgets($client);
Rezultat
Serverul a primit: Salut, server!
Clientul a primit: Salut, Ana!
Exemplul 2: O cerere HTTP scrisă de mână
<?php
$s = fsockopen("www.exemplu.ro", 80, $cod, $mesaj, 5);
fwrite($s, "HEAD / HTTP/1.1\r\nHost: www.exemplu.ro\r\nConnection: close\r\n\r\n");
echo fgets($s);
fclose($s);
Rezultat posibil (depinde de server)
HTTP/1.1 200 OK
Exemplul 3: Tratarea erorii de conectare
Pe portul 1 nu ascultă nimic. @ ascunde avertismentul, iar mesajul vine în $mesaj. Codul din $cod depinde de sistem (111 pe Linux, 61 pe macOS), de aceea afișăm doar mesajul.
<?php
$s = @fsockopen("127.0.0.1", 1, $cod, $mesaj, 2);
if ($s === false) {
echo "Serviciul nu răspunde: $mesaj";
}
Rezultat
Serviciul nu răspunde: Connection refused
Greșeli frecvente
- Nu dai
$timeout. Dacă serverul nu răspunde, scriptul așteaptă 60 de secunde. Pune 2-5 secunde pentru servicii din aceeași rețea. - Scrii
"https://www.exemplu.ro"ca nume.fsockopennu înțelege adrese web; pentru HTTPS foloseștessl://www.exemplu.roși portul 443, sau mai simplufile_get_contentsori cURL. - Citești cu
fgetspână lafeofo conexiune HTTP fărăConnection: close. Serverul ține conexiunea deschisă și bucla așteaptă până la timeout.
Comenzi înrudite
stream_socket_client: Deschide o conexiune către un server dată ca adresă completă (tcp://, udp://, tls://, unix://) și o returnează ca stream.stream_set_timeout: Stabilește cât timp așteaptă o citire de pe un socket înainte să renunțe.fgets: Citește o linie dintr-un fișier deschis cu fopen.fwrite / fputs: Scrie un text într-un fișier deschis cu fopen. fputs este același lucru, cu alt nume.