Guzzle 6 下载文件

问题描述 投票:0回答:4

需要使用 Guzzle 6 从 REST API 下载文件的帮助。我不希望文件保存在本地,而是从网络浏览器下载。代码到目前为止,但相信我错过了一些东西?

    <?php

//code for Guzzle etc removed

$responsesfile = $client->request('GET', 'documents/1234/content', 
        [
        'headers' => [
            'Cache-Control' => 'no-cache', 
            'Content-Type' => 'application/pdf',
            'Content-Type' => 'Content-Disposition: attachment; filename="test"'
        ]
        ]


    );
    return $responsesfile;
    ?>
php guzzle guzzle6
4个回答
44
投票

只需在 Guzzle 的文档中进行研究,例如 here

传递一个字符串来指定存储响应正文内容的文件的路径:

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

传递从 fopen() 返回的资源以将响应写入 PHP 流:

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

传递 Psr\Http\Message\StreamInterface 对象以将响应正文流式传输到开放的 PSR-7 流。

$resource = fopen('/path/to/file', 'w');
$stream = GuzzleHttp\Psr7\stream_for($resource);
$client->request('GET', '/stream/20', ['save_to' => $stream]);

6
投票

stream_for
在版本 7.2 中已弃用。您可以使用
GuzzleHttp\Psr7\Utils::streamFor($resource)
代替。


0
投票

如果来自源 API 的响应(返回实际文件)包含正确的标头,您可以返回文件以供下载,而无需将其保存在任何地方。

只需重用响应中的标头并返回响应正文即可。浏览器将识别返回的响应用于文件下载。

这可能取决于实际的 php 框架以及它如何处理 http 响应,但通常您可以在普通 PHP 中执行类似的操作(请注意,

$downloadResponse
已从 GuzzleHttp
get()
方法返回):

//** @var Psr\Http\Message\ResponseInterface $downloadResponse    
foreach ($downloadResponse->getHeaders() as $headerName => $headerValues) {
    header("$headerName:" . implode(',', $headerValues));
}
echo $downloadResponse->getBody();

另请注意,在上面的示例中,我没有考虑标头值的简单内爆可能导致问题的特殊情况(例如 Set-Cookie 值)。

为了更好地理解,我还添加了来自文件源 API 的正确设置标头的示例,该示例与所提供的代码相结合将导致实际的文件下载:

Date: Mon, 11 Sep 2023 15:22:41 GMT
Content-Type: application/pdf
Content-Length: 6850
Connection: keep-alive
Vary: Origin
Access-Control-Allow-Credentials: true
access-control-allow-origin: *
Content-Disposition: attachment; filename="sample.pdf"
ETag: W/"1ac2-W5cdxxx7R45QxxxnBvKO+R7asd-abc"
Strict-Transport-Security: max-age=15724800; includeSubDomains

-1
投票

首先,

Content-Type
标头仅在发送内容(POST/PUT)时才有意义,但对于 GET 请求则没有意义。

其次,你的问题是什么?默认情况下,Guzzle 不会将响应正文(文件)存储在某处,因此您可以在应用程序中使用它,例如

$responsesfile->getBody()

© www.soinside.com 2019 - 2024. All rights reserved.