Just as a complement to the @Viniciuszaramella response, where he quotes the
requisitions from Guzzle\Http
.
Explanation of the Asymchronism of the Guzzle
Regarding the asynchrony regarding Guzzle requests, I realized that the same, when using the class Pool
actually sends several requests at once background
, having therefore their answers asynchronously.
In case, if we made a request with the Guzzle
, normally without using the Pool
, within a for from 0 to 200, expensive request would await the reply of the other to perform a request.
Example:
$guzzle = new GuzzleHttp\Client;
for ($i = 0; $i < 200; $i++)
{
$guzzle->get('http://httpbin.org/get', ['query' => ['i' => $i]]);
}
In the case of Pool
, requests are sent "at once" - according to the configuration you have in the option concurrency
, which is the number of requests made at a time in the queue.
$requests = function () {
$guzzle = new GuzzleHttp\Client;
for ($i = 0; $i < 200; $i++)
{
yield $guzzle->get('http://httpbin.org/get', ['query' => ['i' => $i]]);
}
};
$pool = new Pool($guzzle, $requests(), [
'concurrency' => 50, // envia de 30 em 30,
'rejected' => function ($exception, $index)
{
},
'fulfilled' => function ($response, $index)
{
}
]);
$poll->promise()->wait();
I performed similar tests on both cases. The result was that, in the case similar to the first example, it took 45 to 50 seconds a request (enough to give that PHP time limit error). In the second case, only 5 to 7 seconds were used in the execution time.
So it really is an effective method.
Other Asynchronmentalism
Before Vinicius' reply was published, I had found on the internet to make asynchronous requests with PHP. However, when performing such an operation, PHP will not wait for the answer, but will only make the request while the code will run normally until the end.
function async_request($method, $url, $params, array $headers = [])
{
$method = strtoupper($method);
$sendData = in_array($method, array('PUT', 'POST'));
$data = http_build_query($params);
$parts = parse_url($url) + [
'port' => 80,
'path' => '/',
];
$headers += [
'Content-Type' => 'application/x-www-form-urlencoded',
'Host' => $parts['host'],
'Content-Length' => !$sendData ? 0 : strlen($data),
'Connection' => 'Close'
];
$path = !$sendData ? $parts['path'] . '?' . $data : $parts['path'];
$output_header = sprintf('%s %s HTTP/1.1', $method, $path) . "\r\n";
foreach ($headers as $name => $value)
{
foreach((array) $value as $v)
{
$output_header .= "$name: $v\r\n";
}
}
$output_header .= "\r\n";
$handle = @fsockopen($parts['host'], $parts['port'], $_errno, $_errstr, 30);
if ($handle === false)
{
throw new \RuntimeException($_errstr);
}
fwrite($handle, $output_header);
if ($sendData) fwrite($handle, $data);
fclose($handle);
return $output_header;
}
You can test in this function as follows:
#index.php
assync_request('GET', 'http://localhost/target.php', []);
echo 'terminou';
#target.php
sleep(5);
file_put_contents('gato.txt', "Meow!!!\n\n", FILE_APPEND);
When you make the request, you will realize that the word 'terminou'
will be displayed immediately. And after 5 seconds, is that the file gato.txt
will be created. This is because php has executed a socket in the backgroud, which is responsible for requesting target.php
.
That was the idea that I had initially about the asynchrony, but anyway the @Viniciuszaramella response served me better.
yes, with sockets :) Your PHP needs to be served by the HTTPD server, or it can run directly?
– Bacco
What a difficult question: What is HTTPD?
– Wallace Maxters
Http Daemon (is the page server). Normally this acronym is used in linux, actually as I used the word server, I should have taken D out of the end. It was a flaw in my edit of the comment.
– Bacco