(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)
socket_select — Executa a chamada de sistema select() nos arrays de soquetes fornecidos com um tempo limite especificado
&$read
,&$write
,&$except
,$seconds
,$microseconds
= 0socket_select() aceita arrays de soquetes e espera que eles mudem de status. Usuários com experiência em soquetes BSD reconhecerão que esses arrays de soquete são na verdade os chamados conjuntos de descritores de arquivos. Três arrays independentes de soquetes são monitoradas.
read
Os soquetes listados no array read
serão
observados para ver se os caracteres ficam disponíveis para leitura (mais
precisamente, para ver se uma leitura não será bloqueada - em particular, um soquete
também estará pronto no final do arquivo, nesse caso uma chamada a
socket_read() retornará uma string de comprimento zero).
write
Os soquetes listados no array write
serão
observados para ver se uma escrita não será bloqueada.
except
Os soquetes listados no array except
serão
observados em busca de exceções.
seconds
Os parâmetros seconds
e microseconds
juntos formam o parâmetro de tempo limite (timeout
). O tempo limite
(timeout
) é um limite superior no tempo
decorrido antes que socket_select() retorne.
seconds
pode ser zero, o que faz com que
socket_select() retorne imediatamente. Isto é útil
para pesquisas. Se seconds
for null
(sem tempo limite),
socket_select() pode bloquear indefinidamente.
microseconds
Na saída, os arrays são modificados para indicar qual soquete realmente mudou de status.
Não é necessário passar todos os arrays para
socket_select(). Em vez disso, pode-se usar um
array vazio ou null
. Também deve-se lembrar que esses arrays são
passados por referência e serão modificados após
o retorno de socket_select().
Nota:
Devido a uma limitação no Motor Zend atual, não é possível passar um modificador constante como
null
diretamente como parâmetro para uma função que espera que esse parâmetro seja passado por referência. Em vez disso, use uma variável temporária ou uma expressão com o membro mais à esquerda sendo uma variável temporária:Exemplo #1 Usando
null
com socket_select()<?php
$e = NULL;
socket_select($r, $w, $e, 0);
?>
Em caso de sucesso, socket_select() retorna o número de
soquetes contidos nos arrays modificados, que pode ser zero se
o tempo limite expirar antes que algo interessante aconteça. Em caso de erro,
retorna false
. O código de erro pode ser recuperado com
socket_last_error().
Nota:
Certifique-se de usar o operador
===
ao verificar se há um erro. Como socket_select() pode retornar 0, a comparação com==
seria avaliada comotrue
:Exemplo #2 Entendendo o resultado de socket_select()
<?php
$e = NULL;
if (false === socket_select($r, $w, $e, 0)) {
echo "socket_select() falhou, motivo: " .
socket_strerror(socket_last_error()) . "\n";
}
?>
Exemplo #3 Exemplo de socket_select()
<?php
/* Prepara o array de leitura */
$read = array($socket1, $socket2);
$write = NULL;
$except = NULL;
$num_changed_sockets = socket_select($read, $write, $except, 0);
if ($num_changed_sockets === false) {
/* Tratamento de erro */
} else if ($num_changed_sockets > 0) {
/* Pelo menos em um dos soquetes algo interessante ocorreu */
}
?>
Nota:
Deve-se ter ciência de que algumas implementações de soquete precisam ser tratadas com muito cuidado. Algumas regras básicas:
- Deve-se sempre tentar usar socket_select() sem tempo limite. A aplicação não deverá ter nada a fazer se não houver dados disponíveis. Código que depende de limites de tempo geralmente não é portável e é difícil de depurar.
- Nenhum soquete deve ser adicionado a nenhum conjunto se não houver intenção de verificar seu resultado após a chamada a socket_select() e de responder apropriadamente. Após o retorno de socket_select(), todos os soquetes em todos os arrays devem ser verificados. Qualquer soquete disponível para escrita deve ser escrito e qualquer soquete disponível para leitura deve ser lido.
- Se um retorno de soquete for lido/escrito nos arrays, eles não necessariamente leem/escrevem a quantidade total de dados solicitada. Deve-se estar preparado para conseguir ler/escrever apenas um único byte.
- É comum na maioria das implementações de soquete que a única exceção capturada com o array
except
sejam dados fora-de-banda recebidos em um soquete.