Upload File in chunks to URL Endpoint using Guzzle

2019-07-29 14:32发布

问题:

I want to upload files in chunks to a URL endpoint using guzzle.

I should be able to provide the Content-Range and Content-Length headers.

Using php I know I can split using

define('CHUNK_SIZE', 1024*1024); // Size (in bytes) of chunk

function readfile_chunked($filename, $retbytes = TRUE) {
    $buffer = '';
    $cnt    = 0;
    $handle = fopen($filename, 'rb');

    if ($handle === false) {
        return false;
    }

    while (!feof($handle)) {
        $buffer = fread($handle, CHUNK_SIZE);
        echo $buffer;
        ob_flush();
        flush();

        if ($retbytes) {
            $cnt += strlen($buffer);
        }
    }

    $status = fclose($handle);

    if ($retbytes && $status) {
        return $cnt; // return num. bytes delivered like readfile() does.
    }

    return $status;
}

How Do I achieve sending the files in chunk using guzzle, if possible using guzzle streams?

回答1:

This method allows you to transfer large files using guzzle streams:

use GuzzleHttp\Psr7;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;

$resource = fopen($pathname, 'r');
$stream = Psr7\stream_for($resource);

$client = new Client();
$request = new Request(
        'POST',
        $api,
        [],
        new Psr7\MultipartStream(
            [
                [
                    'name' => 'bigfile',
                    'contents' => $stream,
                ],
            ]
        )
);
$response = $client->send($request);


回答2:

Just use multipart body type as it's described in the documentation. cURL then handles the file reading internally, you don't need to so implement chunked read by yourself. Also all required headers will be configured by Guzzle.