Funzione PHP socket_get_status(): Tutto Quello che Devi Sapere
Scopri come usare socket_get_status() in PHP per verificare lo stato di uno stream: timeout, eof, byte in buffer e modalità blocking.
Quando si legge da o si scrive su una connessione di rete in PHP, spesso è necessario sapere se la connessione è ancora attiva, se una lettura è scaduta per timeout, o quanti byte sono in attesa nel buffer. La funzione socket_get_status() risponde esattamente a queste domande: restituisce un'istantanea dello stato corrente di uno stream.
Questo capitolo spiega cosa restituisce socket_get_status(), quando ogni campo è rilevante e come usarla in modo sicuro con timeout e stream non bloccanti.
Cos'è la Funzione socket_get_status()?
socket_get_status() recupera lo stato corrente di una risorsa stream come array associativo. È in realtà un alias di stream_get_meta_data(), quindi le due funzioni restituiscono gli stessi dati — socket_get_status() è semplicemente il nome storico mantenuto per il codice di rete.
Nonostante il nome, la funzione è progettata per le risorse stream — del tipo restituite da fsockopen(), pfsockopen() o stream_socket_client() — e non per le risorse socket di basso livello create da socket_create(). Passare il tipo di risorsa errato può generare avvisi di deprecazione in PHP 8+ e non fornirà i dati attesi.
Come Usare la Funzione socket_get_status()
Usare la funzione socket_get_status() è semplice. Ecco la sintassi della funzione:
La sintassi PHP della funzione socket_get_status()
socket_get_status(resource $stream): arrayLa funzione accetta un parametro:
$stream: La risorsa stream di cui si vuole recuperare lo stato.
Restituisce un array associativo. Le chiavi più utili sono:
| Chiave | Tipo | Significato |
|---|---|---|
timed_out | bool | true se l'ultima lettura/scrittura ha raggiunto il timeout dello stream. |
blocked | bool | true se lo stream è in modalità bloccante. |
eof | bool | true se è stata raggiunta la fine dello stream (connessione chiusa). |
unread_bytes | int | Byte già letti nel buffer interno di PHP ma non ancora consumati. |
stream_type | string | Il trasporto sottostante, ad es. tcp_socket/ssl. |
wrapper_type | string | Il wrapper che gestisce lo stream, ad es. http. |
mode | string | La modalità di accesso con cui è stato aperto lo stream, ad es. r+. |
Verificare se una connessione è ancora aperta
Ecco un esempio minimale che apre uno stream TCP, legge una riga e usa socket_get_status() per determinare se il server ha chiuso la connessione:
Come usare la funzione socket_get_status()?
<?php
$stream = fsockopen("tcp://www.example.com", 80, $errno, $errstr, 30);
if (!$stream) {
die("Error: $errstr ($errno)");
}
fwrite($stream, "GET / HTTP/1.0\r\nHost: www.example.com\r\n\r\n");
$line = fgets($stream);
$status = socket_get_status($stream);
echo $status["eof"] ? "Connection closed by server\n" : "Connection still open\n";
fclose($stream);
?>Usiamo fsockopen() per creare uno stream e verificare che sia stato creato correttamente prima di fare qualsiasi altra cosa. Dopo aver inviato una richiesta e letto una riga con fgets(), il campo eof ci indica se il server remoto ha terminato. Chiudi sempre lo stream con fclose() al termine.
Rilevare un timeout di lettura
Il campo timed_out è ciò che rende socket_get_status() davvero utile. Quando si imposta un timeout di lettura con stream_set_timeout() (o socket_set_timeout()), una lettura lenta non genera un'eccezione — fgets() restituisce semplicemente false. Si chiama poi socket_get_status() per scoprire perché ha restituito false:
<?php
$stream = fsockopen("tcp://www.example.com", 80, $errno, $errstr, 30);
if (!$stream) {
die("Error: $errstr ($errno)");
}
// Wait at most 2 seconds for data before giving up.
stream_set_timeout($stream, 2);
$line = fgets($stream); // We never sent a request, so nothing arrives.
$status = socket_get_status($stream);
if ($status["timed_out"]) {
echo "Read timed out\n";
} else {
echo "Got data\n";
}
fclose($stream);
?>Poiché non è stata inviata alcuna richiesta, il server non ha nulla a cui rispondere, scatta il timeout di 2 secondi e lo script stampa Read timed out. Senza socket_get_status() non si potrebbe distinguere un timeout da una fine dello stream vera e propria — entrambi fanno restituire false a fgets().
Quando Usare socket_get_status()
- Dopo una lettura fallita.
fgets()/fread()che restituiscefalseè ambiguo; controllatimed_outeeofper capire cosa è successo. - Prima di riutilizzare una connessione. Ispeziona
eofper confermare che un socket keep-alive sia ancora attivo prima di inviare un'altra richiesta. - Con stream non bloccanti. Quando si chiama
stream_set_blocking()per rendere un socket non bloccante,unread_byteseblockedaiutano a ragionare sui dati nel buffer.
Avvertenze
- Funziona solo con risorse stream — non con risorse
socket_create(). Per queste, usa invecesocket_last_error()/socket_get_option(). socket_get_status()riflette lo stato del buffer e del timeout nel momento in cui viene chiamata; non sonda attivamente la rete, quindi uneofpari afalsenon garantisce che il peer sia ancora raggiungibile.- Reimposta il flag di timeout eseguendo un'altra lettura con successo — l'array viene ricalcolato ad ogni chiamata.
Conclusione
La funzione socket_get_status() è un modo leggero per ispezionare lo stato di uno stream socket in PHP. Il suo campo più prezioso è timed_out, che permette di distinguere un timeout di lettura da una connessione chiusa — qualcosa che il solo valore restituito da fgets() non consente di fare. Combinata con eof, unread_bytes e i controlli di timeout e blocking di stream_set_timeout() e stream_set_blocking(), fornisce le informazioni necessarie per gestire le connessioni di rete in modo affidabile.