在 Guzzle 中使用“sink”选项下载文件会导致文件为空。为什么?以及如何解决?

Using `sink` option in Guzzle to download a file resuls in empty file. Why that? And how to fix it?

我需要使用 Guzzle 下载文件。目前我使用的是 6.3.3 版本。

我将 sink 选项传递给我的请求,但是尽管 API 我请求响应“200 OK”并包含一些正文内容,但目标文件始终为空。

这里是我目前的代码:

// sidenote:
// $this->importFile is the absolute path to the file the contents have to be downloaded to
// $this->api is a GuzzleHttp\Client, base URL has been set previously
// $uri is the API endpoint's URI I am requesting (like "get/data")
// $this->getQueryParams() returns an array with a few needed parameters

$downloadDestination = fopen($this->importFile, 'w');

$response = $this->api->get($uri, [
    'query' => $this->getQueryParams(),
    'sink' => $downloadDestination,
]);

var_dump(file_get_contents($this->importFile));
var_dump($response->getBody()->getContents());
die;

顺便说一下,我是在 Symfony (3.4) 应用程序的上下文中在命令 (bin/console blah:custom-command) 中调用它的。上面的代码片段是我的一项服务的一部分 类.

这会在我的终端中生成一个新创建的空文件和以下输出:

string(0) ""
string(2065) "{"id":"123", … }"
# the latter one is actually a large JSON string, I just shortened it here

有人知道我做错了什么吗?这实际上不是火箭科学。现在我更困惑的是,我的下载目标文件已经创建,但它的内容不会被写入…

Guzzle 或类似的东西是否缺少某种配置?

该死!这绝对是我自己的错。我也应该发布 Guzzle 客户端的初始化。然后我可以稍微早一点发现我的错误......

$this->api = new Client([
    'base_uri' => $apiBaseUrl,
    'stream' => true,
]);

在我添加 sink 选项(将响应正文下载为文件)之前,我的服务 class 必须逐行处理响应(因为 API 我使用最多 1 GB 大小的数据进行响应)。因此我也预先添加了 stream 选项。这个与 sink.

相撞

因此,我的解决方案是简单地从客户端的初始化中删除 stream 选项。 – Et voilà。有效。