socket_select
PHP Manual
PHP Manual»Fonctions sur les sockets»socket_select

socket_select

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

socket_select — Exécute l'appel système select() sur un tableau de sockets avec une durée d'expiration

Description

function socket_select(
    ?array &$read,
    ?array &$write,
    ?array &$except,
    ?int $seconds,
    int $microseconds = 0
): int|false

socket_select() accepte un tableau de sockets et attend qu'elles changent de statut. Ceux qui sont familiers avec les sockets de BSD reconnaîtront dans ces tableaux de sockets les jeux de pointeurs de fichiers. Trois tableaux indépendants de sockets sont surveillés.

Liste de paramètres

read

Les sockets listés dans le paramètre read seront surveillés en lecture : pour savoir quand ils sont disponibles en lecture (plus précisément, si une lecture ne va pas bloquer, en particulier, un socket a déjà atteint une fin de fichier, auquel cas socket_read() retournera une chaîne de taille zéro).

write

Les sockets listés dans write seront surveillés en écriture : pour voir si une écriture ne va pas bloquer.

except

Les sockets listés dans except seront surveillés pour leurs exceptions.

seconds

Les paramètres seconds et microseconds ensembles forment le paramètre timeout (délai d'expiration). Le timeout est la durée maximale de temps avant que socket_select() ne se termine. seconds peut être zéro, ce qui fera que socket_select() retournera immédiatement. C'est très pratique pour faire du polling (sondage). Si seconds est null (pas de timeout), socket_select() peut se bloquer indéfiniment.

microseconds

Voir la description de seconds.

Avertissement

En sortie de fonction, les tableaux sont modifiés pour indiquer quels sockets ont changé d'état. Les clés d'origine des tableaus sont préservées.

Les trois tableaux doivent tous être fournis, mais un tableau sans intérêt peut être un tableau vide ou null ; au moins l'un d'entre eux doit être un tableau non vide. Ils sont passés par référence et sont modifiés une fois que socket_select() a retourné.

Note:

À cause d'une limitation du moteur Zend actuel, il n'est pas possible de passer une constante comme null directement comme paramètre à cette fonction, qui attend une valeur par référence. À la place, utiliser un tableau temporaire ou une expression dont le membre de gauche est une variable temporaire :

Exemple #1 Passer null à socket_select()

<?php
$e = NULL;
socket_select($r, $w, $e, 0);
?>

Valeurs de retour

En cas de succès, socket_select() retourne le nombre de sockets contenues dans les tableaux modifiés. Ce nombre peut être zéro si la durée maximale d'attente a été atteinte. En cas d'erreur, false est retourné. Le code d'erreur généré peut être obtenu en appelant la fonction socket_last_error().

Note:

Il faut s'assurer bien d'utiliser l'opérateur === lorsque l'on vérifie les erreurs. Étant donné que socket_select() peut retourner 0, la comparaison avec false via == donnerait true :

Exemple #2 Analyser le résultat de socket_select()

<?php
$e = NULL;
if (false === socket_select($r, $w, $e, 0)) {
    echo "socket_select() a échoué. Raison : " .
        socket_strerror(socket_last_error()) . "\n";
}
?>

Exemples

Exemple #3 Exemple avec socket_select()

<?php
/* Prépare le tableau read (socket surveillées en lecture) */
$read   = array($socket1, $socket2);
$write  = NULL;
$except = NULL;
$num_changed_sockets = socket_select($read, $write, $except, 0);

if ($num_changed_sockets === false) {
  /* Gestion des erreurs */
} else if ($num_changed_sockets > 0) {
  /* Au moins une des sockets a été modifiée */
}
?>

Notes

Note:

Il faut se méfier des implémentations de sockets, qui doivent être manipulées avec délicatesse. Quelques règles de base :

  • Il faut toujours essayer d'utiliser socket_select() sans timeout. Le programme ne devrait avoir rien à faire si il n'y a pas de données disponibles. Le code qui dépend d'un timeout est généralement peu portable, et difficile à déboguer.

  • Un socket ne doit pas être ajouté à l'un des tableaux en paramètre, si on ne souhaite pas vérifier le résultat après l'appel à socket_select(). Après le retour de socket_select(), tous les sockets dans tous les tableaux doivent être vérifiés. Tout socket qui est disponible en écriture ou en lecture doit être utilisé pour écrire ou lire.

  • Lors de la lecture ou de l'écriture sur un socket retourné dans les tableaux, il faut savoir que la totalité des données demandées n'est pas nécessairement lue ou écrite. Il faut être prêt à ne traiter qu'un seul octet.

  • Il est commun à la plupart des implémentations de socket que la seule exception interceptée par les sockets dans le tableau except soit le cas des données hors limites, reçues par un socket.

Voir aussi

To Top