Existe uma maneira no PHP de fazer chamadas HTTP assíncronas? Não me preocupo com a resposta, só quero fazer algo assim file_get_contents()
, mas não espere a solicitação terminar antes de executar o restante do meu código. Isso seria super útil para desencadear "eventos" de um tipo no meu aplicativo ou desencadear processos longos.
Alguma ideia?
php
http
asynchronous
Brent
fonte
fonte
Respostas:
A resposta que eu aceitei anteriormente não funcionou. Ainda esperava respostas. No entanto, isso funciona, retirado de Como faço uma solicitação GET assíncrona em PHP?
fonte
curl_post_async
e obter até upvotes ...Se você controlar o destino que deseja chamar de forma assíncrona (por exemplo, seu próprio "longtask.php"), poderá fechar a conexão a partir desse fim, e os dois scripts serão executados em paralelo. Funciona assim:
Eu tentei isso, e funciona muito bem. Mas o quick.php não saberá nada sobre o desempenho do longtask.php, a menos que você crie algum meio de comunicação entre os processos.
Experimente esse código no longtask.php, antes de fazer qualquer outra coisa. Ele fechará a conexão, mas continuará sendo executado (e suprimirá qualquer saída):
O código é copiado das notas fornecidas pelo usuário do manual do PHP e um pouco melhorado.
fonte
while(true);
após o seu código. A página irá travar, isso significa que ainda está sendo executada em primeiro plano.Você pode fazer truques usando exec () para chamar algo que possa fazer solicitações HTTP, como
wget
, mas você deve direcionar toda a saída do programa para algum lugar, como um arquivo ou / dev / null, caso contrário, o processo PHP aguardará essa saída .Se você deseja separar o processo completamente do thread do apache, tente algo como (não tenho certeza disso, mas espero que você entenda):
Não é um bom negócio, e você provavelmente desejará algo como um trabalho cron chamando um script de pulsação que pesquisa uma fila de eventos de banco de dados real para realizar eventos assíncronos reais.
fonte
exec("curl $url > /dev/null 2>&1 &");
é uma das soluções mais rápidas aqui. É imensamente mais rápido (1,9s para 100 iterações) do que apost_without_wait()
função (14,8s) na resposta "aceita" acima. E é um one-liner ...A partir de 2018, o Guzzle se tornou a biblioteca padrão padrão para solicitações HTTP, usada em várias estruturas modernas. Está escrito em PHP puro e não requer a instalação de extensões personalizadas.
Ele pode fazer chamadas HTTP assíncronas muito bem e até agrupá-las , como quando você precisa fazer 100 chamadas HTTP, mas não deseja executar mais de 5 por vez.
Exemplo de solicitação simultânea
Consulte http://docs.guzzlephp.org/en/stable/quickstart.html#concurrent-requests
fonte
fonte
&
no final?Você pode usar esta biblioteca: https://github.com/stil/curl-easy
É bem simples então:
Abaixo você pode ver a saída do console do exemplo acima. Ele exibirá um relógio ao vivo simples, indicando quanto tempo a solicitação está em execução:
fonte
Fingir um pedido de aborto usando
CURL
um valor baixoCURLOPT_TIMEOUT_MS
definido
ignore_user_abort(true)
para continuar o processamento após o fechamento da conexão.Com este método, não é necessário implementar o tratamento de conexões por meio de cabeçalhos e buffer, dependendo da versão do SO, navegador e PHP
Processo mestre
Processo em segundo plano
NB
Recursos
tempo limite de ondulação inferior a 1000ms sempre falha?
http://www.php.net/manual/en/function.curl-setopt.php#104597
http://php.net/manual/en/features.connection-handling.php
fonte
deixe-me mostrar o meu caminho :)
precisa do nodejs instalado no servidor
(meu servidor envia 1000 solicitações de obtenção https https leva apenas 2 segundos)
url.php:
urlscript.js>
fonte
A extensão swoole. https://github.com/matyhtf/swoole Estrutura de rede assíncrona e simultânea para PHP.
fonte
Você pode usar soquetes sem bloqueio e uma das extensões pecl para PHP:
Você pode usar a biblioteca que fornece uma camada de abstração entre seu código e uma extensão pecl: https://github.com/reactphp/event-loop
Você também pode usar o cliente http assíncrono, com base na biblioteca anterior: https://github.com/reactphp/http-client
Veja outras bibliotecas do ReactPHP: http://reactphp.org
Tenha cuidado com um modelo assíncrono. Eu recomendo ver este vídeo no youtube: http://www.youtube.com/watch?v=MWNcItWuKpI
fonte
fonte
Extensão de evento
A extensão de evento é muito apropriada. É uma porta da biblioteca Libevent, projetada para E / S orientada a eventos, principalmente para redes.
Eu escrevi um cliente HTTP de amostra que permite agendar uma série de solicitações HTTP e executá-las de forma assíncrona.
Esta é uma classe de cliente HTTP de amostra com base na extensão de Evento .
A classe permite agendar uma série de solicitações HTTP e executá-las de forma assíncrona.
http-client.php
test.php
Este é um script de amostra no lado do servidor.
Uso
Saída de amostra
(Aparado.)
Observe que o código foi projetado para processamento a longo prazo na CLI SAPI .
Para protocolos personalizados, considere o uso de API de baixo nível, ou seja , eventos de buffer , buffers . Para comunicações SSL / TLS, eu recomendaria a API de baixo nível em conjunto com o contexto SSL do evento . Exemplos:
Embora a API HTTP da Libevent seja simples, ela não é tão flexível quanto os eventos do buffer. Por exemplo, a API HTTP atualmente não suporta métodos HTTP personalizados. Mas é possível implementar virtualmente qualquer protocolo usando a API de baixo nível.
Extensão Ev
Também escrevi uma amostra de outro cliente HTTP usando a extensão Ev com soquetes no modo sem bloqueio . O código é um pouco mais detalhado que o exemplo baseado em Event, porque Ev é um loop de eventos de uso geral. Ele não fornece funções específicas da rede, mas seu
EvIo
observador é capaz de ouvir um descritor de arquivo encapsulado no recurso de soquete, em particular.Este é um exemplo de cliente HTTP baseado na extensão Ev .
A extensão Ev implementa um loop de eventos de uso geral simples, porém poderoso. Ele não fornece observadores específicos da rede, mas seu observador de E / S pode ser usado para processamento assíncrono de soquetes .
O código a seguir mostra como as solicitações HTTP podem ser agendadas para processamento paralelo.
http-client.php
Teste
Suponha que o
http://my-host.local/test.php
script esteja imprimindo o dump de$_GET
:Em seguida, a saída do
php http-client.php
comando será semelhante à seguinte:(aparado)
Note-se, em PHP 5 a tomadas de extensão pode logar avisos para
EINPROGRESS
,EAGAIN
eEWOULDBLOCK
errno
valores. É possível desligar os logs comEm relação ao "resto" do código
O código que deve ser executado paralelamente às solicitações de rede pode ser executado no retorno de chamada de um timer de eventos , ou no observador ocioso de Ev , por exemplo. Você pode descobrir isso facilmente assistindo as amostras mencionadas acima. Caso contrário, vou adicionar outro exemplo :)
fonte
Aqui está um exemplo de trabalho, basta executá-lo e abrir storage.txt depois, para verificar o resultado mágico
fonte
Aqui está minha própria função PHP quando POST para um URL específico de qualquer página .... Exemplo: *** uso da minha função ...
fonte
Cliente http assíncrono do ReactPHP
https://github.com/shuchkin/react-http-client
Instalar via Composer
GET HTTP assíncrono
Execute o php no modo CLI
fonte
Acho este pacote bastante útil e muito simples: https://github.com/amphp/parallel-functions
Ele carregará todos os 3 URLs em paralelo. Você também pode usar métodos de instância de classe no fechamento.
Por exemplo, eu uso a extensão Laravel com base neste pacote https://github.com/spatie/laravel-collection-macros#parallelmap
Aqui está o meu código:
Carrega todos os dados necessários em 10 threads paralelos e, em vez de 50 segundos sem assíncrono, termina em apenas 8 segundos.
fonte
O Symfony HttpClient é assíncrono https://symfony.com/doc/current/components/http_client.html .
Por exemplo, você pode
fonte
Bem, o tempo limite pode ser definido em milissegundos, consulte "CURLOPT_CONNECTTIMEOUT_MS" em http://www.php.net/manual/en/function.curl-setopt
fonte