How can I asynchronously download files with Guzzle 6?

M. Ivanov picture M. Ivanov · Aug 24, 2015 · Viewed 11k times · Source

I am trying to asynchronously download files with Guzzle 6, but the documentation seems vague and couldn't find any useful examples.

The thing I am not sure about is - how am I supposed to save the received data?

Currently I am doing it like this:

$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);
};

Is this really asynchronous?

Since if we get into one callback and start looping, how can we get the data from the other ones at the same time?

Is there a more direct way to tell, when creating a Request, where should the response be stored? (or directly passing a stream for that).

Answer

localheinz picture localheinz · Dec 23, 2015

The sink option should be your friend here:

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

For reference, see http://docs.guzzlephp.org/en/latest/request-options.html#sink.