需要使用 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;
?>
只需在 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]);
stream_for
在版本 7.2 中已弃用。您可以使用
GuzzleHttp\Psr7\Utils::streamFor($resource)
代替。
如果来自源 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
首先,
Content-Type
标头仅在发送内容(POST/PUT)时才有意义,但对于 GET 请求则没有意义。
其次,你的问题是什么?默认情况下,Guzzle 不会将响应正文(文件)存储在某处,因此您可以在应用程序中使用它,例如
$responsesfile->getBody()
。