PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

stream_set_blocking> <stream_resolve_include_path
Last updated: Fri, 04 Jul 2008

view this page in

stream_select

(PHP 4 >= 4.3.0, PHP 5)

stream_select — Ejecuta el equivalente al llamado de sistema select() en la matriz de secuencias dada, con un tiempo de espera especificado por tv_sec y tv_usec

Descripción

int stream_select ( array &$lectura , array &$escritura , array &$excepcional , int $tv_sec [, int $tv_usec ] )

La función stream_select() acepta una matriz de secuencias y espera a que éstas cambien su status. Su operación es equivalente a la de la función socket_select(), excepto que actúa sobre secuencias.

Las secuencias listadas en la matriz lectura serán vigiladas para ver si aparecen caracteres disponibles para lectura (o más precisamente, para ver si una operación de lectura no producirá un bloqueo - en particular, un recurso de secuencia se encuentra listo también al llegar al final del archivo, en cuyo caso un llamado a fread() devolverá una cadena de longitud cero).

Las secuencias listadas en la matriz escritura serán vigiladas para ver si una escritura no crea bloqueos.

Las secuencias listadas en la matriz excepcional serán vigiladas por la llegada de datos excepcionales ("out-of-band") de alta prioridad.

Note: Cuando stream_select() devuelve un valor, las matrices lectura , escritura y excepcional son modificadas para indicar cuáles recursos de secuencia modificaron su status en realidad.

Los parámetros tv_sec y tv_usec , juntos forman el parámetro tiempo de espera, tv_sec especifica el número de segundos, mientras que tv_usec el número de microsegundos. El tiempo de espera es un límite superior sobre la cantidad de tiempo que stream_select() esperará antes de devolver un valor. Si tanto tv_sec como tv_usec son definidos como 0, stream_select() no esperará por datos - en su lugar devolverá un valor inmediatamente, indicando el status actual de las secuencias. Si tv_sec es NULL stream_select() puede crear un bloqueo indefinidamente, y sólo devolverá un valor cuando ocurra un evento en alguna de las secuencias vigiladas (o si una señal interrumpe el llamado de sistema).

En caso de éxito, stream_select() devuelve el número de recursos de secuencia modificados contenidos en las matrices, que puede ser cero si el tiempo de espera expira antes de que algo interesante suceda. En caso de fallo, el valor FALSE es devuelto y se genera una advertencia (esto puede pasar si el llamado de sistema es interrumpido por una señal entrante).

Warning

El uso de un valor de tiempo de espera de 0 le permite consultar el status de las secuencias de forma instantánea, sin embargo, NO es buena idea usar un valor de tiempo de espera de 0 en un ciclo, dado que causará que su script consuma mucho tiempo de CPU.

Es mucho mejor especificar un valor de tiempo de espera de algunos pocos segundos, aunque si necesita hacer chequeos y ejecutar otro segmento de código concurrentemente, usar un valor de tiempo de espera de por lo menos 200000 microsegundos le ayudará a reducir el uso de CPU de su script.

Recuerde que el valor de tiempo de espera es el tiempo máximo que transcurrirá; stream_select() devolverá un valor tan pronto como las secuencias solicitadas se encuentren listas para su uso.

No necesita pasar cada matriz a stream_select(). Puede dejar de especificarlas y usar una matriz vacía o NULL en su lugar. Tampoco olvide que estas matrices son pasadas por referencia y serán modificadas después de que stream_select() devuelva un valor.

Este ejemplo revisa si han llegado datos para lectura ya sea en $secuencia1 o en $secuencia2 . Dado que el valor de tiempo de espera es 0, la función retornará inmediatamente:

<?php
/* Preparar la matriz de lectura */
$lectura   = array($secuencia1$secuencia2);
$escritura  NULL;
$excepcional NULL;
if (
false === ($num_secuencias_modificadas stream_select($lectura$escritura$excepcional0))) {
    
/* Gestión de errores */
} elseif ($num_secuencias_modificadas 0) {
    
/* En por lo menos una de las secuencias ha ocurrido algo interesante */
}
?>

Note: Debido a una limitación en el Motor Zend actual, no es posible pasar un modificador constante como NULL directamente como parámetro a una función que espera que tal parámetro sea pasado por referencia. En su lugar, use una variable temporal o una expresión en donde el miembro del lado izquierdo sea una variable temporal:

<?php
$ex 
NULL;
stream_select($lec$esc$ex0);
?>

Note: Asegúrese de usar el operador === cuando efectúe chequeos de error. Dado que stream_select() puede devolver 0, la comparación con == evaluaría a TRUE:

<?php
$ex 
NULL;
if (
false === stream_select($lec$esc$ex0)) {
    echo 
"stream_select() falló\n";
}
?>

Note: Si lee/escribe sobre una secuencia devuelta con las matrices, tenga en cuenta que éstas no necesariemente leen/escriben la cantidad completa de datos que usted ha solicitado. Prepárese para gestionar incluso la lectura/escritura de un solo byte.

Note: Compatibilidad con Windows: El uso de stream_select() sobre un pipe devuelto desde proc_open() puede causar pérdida de datos bajo Windows 98.
El uso de stream_select() con descriptores de archivo devueltos por proc_open() fallará y devolverá FALSE bajo Windows.

Vea también stream_set_blocking().



stream_set_blocking> <stream_resolve_include_path
Last updated: Fri, 04 Jul 2008
 
add a note add a note User Contributed Notes
stream_select
Maxdamantus
30-Sep-2007 07:28
Simple stream_select wrapper.. Returns the first stream in the array, and sets parameter 2 to the key (So that it is easy to identify what received data):

<?php
function select($array, &$vkey, $timeout=0){
   
$select = array();
   
$null = NULL;
    foreach(
$array as $key => $sock){
       
$x = count($select);
       
$select[$x] = $sock;
       
$keys[$x] = $key;
    }
    if(
stream_select($select, $null, $null, $timeout)){
        foreach(
$keys as $key){
            if(
$array[$key] == $select[0]){
               
$vkey = $key;
                return(
$select[0]);
            }
        }
    }
}

$streams = array("foo" => $stream_one, "bar" => $stream_two); // Create an array of two (already existant) streams.
if($new = select($streams, $key, 60)){ //Sets $new to the resource that next gets new data, and $key to either "foo", or "bar", depending which one it is.
   
echo $key.":".stream_get_line($new, 2048)."\n";
}
?>
bluej100@gmail
22-Aug-2007 01:31
@mbaynton at gmail dot com

A handy syntactic trick:

<?php
$r
= Array($stream1, $stream2);
stream_select($r, $w = null, $x = null, 1337);
?>

I've seen it recommended elsewhere in the documentation for clarifying magic arguments so maintainers don't have to go check the function itself, but it also solves your problem here.
mbaynton at gmail dot com
17-Aug-2007 04:35
The documentation states that:

You do not need to pass every array to stream_select(). You can leave it out and use an empty array or NULL instead. Also do not forget that those arrays are passed by reference and will be modified after stream_select() returns.

This appears to be incorrect, at least in PHP 5.1.6, because PHP sees these parameters are passed by reference and thus insists on a bona fide variable for the reference to refer to:

Fatal error: Only variables can be passed by reference

is what you get if you pass NULL or anything else literally.
Ben
02-Feb-2007 02:35
You can key on file descriptors just fine by casting them to an int or a string, which returns what you would expect.
maartenwolzak at gmail dot com
25-Jan-2007 10:36
Note that you should change the calctimeout function below to divide the outcome by 1.000.000 otherwise you'll be waiting for two years instead of one minute for the socket to timeout...

<?php

// The function to calculate the timeout
function calctimeout($maxtime, $starttime)
{
   return (
$maxtime - ((microtime(true) - $starttime) * 1000000))/1000000;
}

?>
aidan at aidans dot org
08-Dec-2006 04:53
Note that contrary to what the previous poster said, one is not able to use a stream resource as a key for an array. Rather, if you want to know which socket you are dealing with, consider using code similar to this:

<?php
$sockets
= array("sock_1" => $sock1, "sock_2" => $sock2, "sock_3" => $sock_3);

$read = $write = $error = $sockets;
$num = stream_select($read, $write, $error, 10);
if (
$n > 0) {
    foreach (
$read as $r) {
       
$key = array_search($r, $sockets);
       
// $key will be "sock_1", "sock_2", "sock_3", etc.
   
}
}
?>

Hope that helps someone out there!
phpdoc at shemesh dot biz
14-Mar-2005 10:33
Please note that, on return, the key of "read" will be zero based, serially numbered according to the streams for which there is read data ready only. In other words, if you want to know which of the original streams placed in "read" is ready, there is no immediate way of knowing that.

If you want to know which of the original stream is which, you can either use "==", or possibly set a reverse map array, in which the stream is the key, and the key to the original "read" array is the data.
aidan at php dot net
22-Jun-2004 08:30
If you want to set an absolute maximum execution time for stream_select in a loop, it's important to decrement the max_time value passed to stream_select.

<?php
// The maximum time for execution in milliseconds
$maxtime = 200000;
// The time the loop started
$starttime = microtime(true);
// Original array of sockets
$r = $orig_sockets;

// The function to calculate the timeout
function calctimeout($maxtime, $starttime)
{
    return
$maxtime - ((microtime(true) - $starttime) * 1000000);
}

while (
stream_select($r, $w = null, $e = null, 0, calctimeout($maxtime, $starttime)) !== 0)
{
   
// loop through the sockets that showed activity
   
foreach ($r as $socket) {
       
// $socket talked
   
}

   
// stream_select modifies the contents of $r
    // in a loop we should replace it with the original
   
$r = $orig_sockets;
}

?>

stream_set_blocking> <stream_resolve_include_path
Last updated: Fri, 04 Jul 2008
 
 
show source | credits | sitemap | contact | advertising | mirror sites