(PHP 4 >= 4.1.0, PHP 5, PHP 7)
socket_select — Executa a chamada de sistema select() nos arrays dados de sockets com um timeout especificado
$&read
, array $&write
, array $&except
, int $tv_sec
[, int $tv_usec
] )Esta função é EXPERIMENTAL. O comportamento, seu nome e documentação podem mudar sem aviso em futuras versões do PHP. Utilize por sua própria conta e risco.
socket_select() aceita arrays de sockets e aguarda até que seu status seja alterado. Estes vem com "background" de sockets BSD irá reconhecer aquele array de socket resource são de fato a chamada ao arquivo descritor de configuração (fds). Três arrays independentes de socket resources são observados.
A lista de sockets no array read
irá ser mostrada para
ver se o caractere disponível anterior à leitura (mais precisamente, para ver se a leitura
não está obstruída - em particular, um socket resource está também no fim-de-arquivo (EOF) , neste caso
o socket_read() irá retornar uma string com comprimento zero.
A lista de sockets no array write
irá ser visualizada
para mostrar se não é uma escrita não está obstruída.
A lista de sockets no array except
irá mostrar
caso haja exceções.
Na saída, os arrays são modificados para indicar qual socket resource atualmente alterou seu status.
Você não precisa passar cada array para
socket_select(). Você pode deixá-los de fora e usar um
array vazio ou NULL
ao invés disso. Também não se esqueça que esses arrays são passados
by reference e irão ser modificados após o retorno de
socket_select().
Exemplo #1 Exemplo de socket_select()
<?php
/* Prepare the read array */
$read = array($socket1, $socket2);
$num_changed_sockets = socket_select($read, $write = NULL, $except = NULL, 0);
if ($num_changed_sockets === false) {
/* Error handling */
} else if ($num_changed_sockets > 0) {
/* At least at one of the sockets something interesting happened */
}
?>
Nota:
Devido a uma limitação no atual Zend Engine não é possível passar um modificador de constante como
NULL
diretamente como parâmetro para uma função que tem exceção para este parâmetro sendo passado por referência. Ao invés disso use uma variável temporária ou uma expressão com o leftmost member sendo uma variável temporária:Exemplo #2 Usando
NULL
com socket_select()<?php
socket_select($r, $w, $e = NULL, 0);
?>
O tv_sec
e tv_usec
juntos formam o parâmetro timeout. O
timeout é o limite máximo da quantidade de tempo passado
antes do retorno de socket_select().
tv_sec
deve ser zero , causando o retorno imediato de
socket_select(). Isso é útil para polling. Se tv_sec
é NULL
(sem timeout),
socket_select() pode bloquear definitivamente.
Em caso de sucesso socket_select() retorna o número
de socket resorces contidos nos arrays modificados, que deve ser zero se
alguma coisa interessante acontecer antes do timeout expirar. Em caso de erro, FALSE
é retornado. O código do erro pode ser retornado com
socket_last_error().
Nota:
Tenha certeza de usar o operador === quando checar por um erro. Desde de que socket_select() deve retornar 0 a comparação com == deve retornar
TRUE
:Exemplo #3 Entendendo resultados de socket_select()
<?php
if (false === socket_select($r, $w, $e = NULL, 0)) {
echo "socket_select() failed, reason: " .
socket_strerror(socket_last_error()) . "\n";
}
?>
Nota:
Esteja consciente que algumas implementações de sockets precisam ser manuseadas com muito cuidado. As regras básicas:
- Você deve sempre tentar usar socket_select() sem timeout. Seu programa não deve fazer nada se não há dados disponíveis. Códigos que dependem de timeouts não são usualmente portáveis e dificultam o debug.
- No socket resource deve ser adicionado alguma configuração se você não pretende checar o resultado após a chamada de socket_select(), e responder de forma apropriada. Após o retorno de socket_select(), todos os sockets resources em todos os arrays devem ser checados. Algum socket resource que está disponível para escrita deve ser escrito, e algum socket resource disponível para leitura deve ser lido.
- Se você está lendo/escrevendo um retorno de socket em array esteja consciente que eles não necessariamente estão lendo/escrevendo a quantidade completa de dados que você requisitou. Esteja preparado para somente habilitar para leitura/escrita um único byte.
- Isso é comum na grande maioria de implementações de socket que pegam exceções através do
except
array está fora do limite de dados recebidos no socket.
Veja também socket_read(), socket_write(), socket_last_error() e socket_strerror().