An alternative is the use of non-blocking asynchronous I/O, which is popular for being used in Nodejs and Javascript. This form of processing allows you to start writing or reading operations simultaneously on a single thread. Today there are libraries in PHP that facilitate the use of this approach. One of them is the Amp I chose to use for example because of HTTP request support, database and API simplicity.
Example:
?php
require __DIR__ . '/vendor/autoload.php';
use Amp\Loop;
use Amp\Artax\Request;
use Amp\Artax\DefaultClient;
/**
* Faz uma requisição assíncrona em alguma das APIs que integramos
*
* @param string $url URL alvo da requisição HTTP
* @param string $listKey Chave do objeto retornado que contém os itens
* @param string $jokeKey Chave dos itens que contém a piada
* @return Amp\Promise Representa o resultado da operação assíncrona
*/
function requestApi($url, $listKey, $jokeKey) {
// A função Amp\call converte um generator em uma promise, dentro dela e da Loop::run
// as instruções yield esperam pela resposta de uma promise. Durante essa espera o
// loop de eventos vai estar trabalhando em outros códigos, assim evitando
// o bloqueio do processo
return Amp\call(function () use ($url, $listKey, $jokeKey) {
$client = new DefaultClient;
$request = (new Request($url))->withHeader('Accept', 'application/json');
$response = yield $client->request($request); // Até aqui o objeto contém apenas os headers HTTP
$json = json_decode(yield $response->getBody(), true);
return array_column($json[$listKey], $jokeKey);
});
}
/**
* A função Loop:run gerencia o código assíncrono e permite que yield seja usado para aguardar
* o retorno das operações
*/
Loop::run(function () {
// Enviar um array para o yield faz com que as requisições sejam feitas simultaneamente!
$jokeResults = yield [
'dad' => requestApi('https://icanhazdadjoke.com/search?term=food', 'results', 'joke'),
'chuckNorris' => requestApi('https://api.chucknorris.io/jokes/search?query=food', 'result', 'value'),
];
// Por causa do "yield" o array joke results vai conter o resultado das requisições, que são
// algumas piadas aleatórias.
foreach (array_merge($jokeResults['dad'], $jokeResults['chuckNorris']) as $joke) {
echo "$joke\n";
}
});
You can solve this with Ajax too, which by default is already asynchronous.
https://answall.com/questions/27401/executar-fun%C3%A7%C3%A3o-php-de-forma-ass%C3%Adncrona
– Rafael Salomão