stream_select în PHP

Stream-uri PHP 4.3+

Așteaptă până când unul sau mai multe stream-uri (socket-uri, pipe-uri) au date de citit sau pot primi date.

Sintaxă
stream_select(?array &$read, ?array &$write, ?array &$except, ?int $seconds, ?int $microseconds = null): int|false

Ce face stream_select

stream_select primește liste de stream-uri și așteaptă până când cel puțin unul este gata. La final, listele sunt modificate și rămân în ele doar stream-urile gata. Așa un singur script poate servi mai mulți clienți sau citi din mai multe procese fără să se blocheze pe unul singur.

$seconds și $microseconds dau timpul maxim de așteptare. 0 verifică și returnează imediat, iar null așteaptă oricât. Listele pe care nu le folosești se dau ca variabile cu valoarea null.

Parametri

Parametru Descriere
$read Stream-urile urmărite pentru citire. Prin referință: după apel rămân doar cele cu date.
$write Stream-urile urmărite pentru scriere, sau null.
$except Stream-urile urmărite pentru date urgente, sau null. Rar folosit.
$seconds Secundele de așteptare. null înseamnă fără limită.
$microseconds Opțional. Microsecunde adăugate la secunde.

Ce returnează

Numărul de stream-uri gata (0 dacă timpul a expirat) sau false la eroare.

Exemple

Exemplul 1: Care conexiune are date?

<?php
[$ana_trimite, $ana] = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
[$ion_trimite, $ion] = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
$nume = [(int) $ana => "Ana", (int) $ion => "Ion"];

fwrite($ion_trimite, "Bună!");

$citire = [$ana, $ion];
$scriere = null;
$exceptii = null;
$gata = stream_select($citire, $scriere, $exceptii, 1);

echo "Gata: $gata\n";
foreach ($citire as $s) {
    echo $nume[(int) $s] . " a trimis: " . fread($s, 100) . "\n";
}

Rezultat

Gata: 1
Ion a trimis: Bună!

Exemplul 2: Verificare fără așteptare

Cu timpul 0, funcția returnează imediat 0 dacă nu sunt date.

<?php
[$a, $b] = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);

$citire = [$b];
$nimic = null;
var_dump(stream_select($citire, $nimic, $nimic, 0));
var_dump(count($citire));

Rezultat

int(0)
int(0)

Greșeli frecvente

  • Refolosești tabloul $citire în buclă fără să-l refaci. După primul apel conține doar stream-urile care erau gata, iar celelalte nu mai sunt urmărite. Construiește-l din nou la fiecare pas.
  • Dai null pentru toate cele trei liste. PHP aruncă ValueError: No stream arrays were passed.
  • Verifici cu if (!stream_select(...)). 0 (timpul a expirat) și false (eroare) sunt situații diferite. Compară cu === false.

Comenzi înrudite

  • stream_set_blocking: Alege dacă citirile dintr-un stream așteaptă date (blocant) sau returnează imediat ce este disponibil.
  • stream_socket_server: Creează un socket de server care ascultă pe o adresă și un port, pentru conexiuni primite cu stream_socket_accept.
  • proc_open: Pornește un proces cu control complet: canale separate pentru intrare, ieșire și erori, director și variabile de mediu proprii.