Как я могу асинхронно скачивать файлы с Guzzle 6?

Я пытаюсь асинхронно загружать файлы с помощью Guzzle 6, но документация кажется расплывчатой ​​и не может найти никаких полезных примеров.

В чем я не уверен — как мне сохранить полученные данные?

В настоящее время я делаю это так:

$successHandler = function (Response $response, $index) use ($files) {
$file = fopen($files[$index], 'a');
$handle = $response->getBody();

while (!$handle->eof()) {
fwrite($file, $handle->read(2048));
}

fclose($file);
};

Это действительно асинхронный?

Поскольку, если мы перейдем к одному обратному вызову и начнем цикл, как мы можем получить данные от других одновременно?

Есть ли более прямой способ указать, при создании запроса, где должен храниться ответ? (или непосредственно для этого передавая поток).

7

Решение

sink Вариант должен быть вашим другом здесь:

$client->request('GET', '/stream/20', [
'sink' => '/path/to/file',
]);

Для справки см. http://docs.guzzlephp.org/en/latest/request-options.html#sink.

11

Другие решения

use function GuzzleHttp\Psr7\stream_for;
use GuzzleHttp\RequestOptions;
use GuzzleHttp\Client;

$tmpFile  = tempnam(sys_get_temp_dir(), uniqid(strftime('%G-%m-%d')));
$resource = fopen($tmpFile, 'w');
$stream   = stream_for($resource);

$client   = new Client();
$options  = [
RequestOptions::SINK            => $stream, // the body of a response
RequestOptions::CONNECT_TIMEOUT => 10.0,    // request
RequestOptions::TIMEOUT         => 60.0,    // response
];

$response = $client->request('GET', 'https://github.com/robots.txt', $options);

$stream->close();
fclose($resource);

if ($response->getStatusCode() === 200) {
echo file_get_contents($tmpFile); // content
}
3

По вопросам рекламы [email protected]