【问题标题】:How to send files with Guzzle without loading them into memory如何使用 Guzzle 发送文件而不将它们加载到内存中
【发布时间】:2021-08-16 01:49:09
【问题描述】:

我有一个表单,我可以在其中将多个文件上传到我的 laravel 后端,然后我想用 Guzzle 将所有这些文件发送到外部 API

如果我上传的 MB 比可用内存多,我的脚本会出现内存不足的问题。错误信息是

允许的内存大小...字节用尽(试图分配...字节)

很遗憾,我无法动态更改内存限制

这是我使用的代码

// in laravel controller method

/* @var \Illuminate\Http\Request $request */
$files = $request->allFiles();

$filesPayload = [];

foreach ($files as $key => $file) {
    $filesPayload[] = [
        'name'     => $key,
        'contents' => file_get_contents($file->path()),
        // 'contents' => fopen($file->path(), 'r'), // memory issue as well
        'filename' => $file->getClientOriginalName(),
    ];
}

$client = new \GuzzleHttp\Client\Client([
    'base_uri' => '...',
]);

$response = $client->post('...', [
    'headers' => [
        'Accept'         => 'application/json',
        'Content-Length' => ''
    ],
    'multipart' =>  $filesPayload,
]);

我正在使用 Guzzle 6。In the docs 我找到了 fopen 的示例,但这也引发了内存错误

有没有办法用 Guzzle 发送多个文件而不将它们加载到内存中?

【问题讨论】:

标签: php laravel guzzle guzzle6


【解决方案1】:

为了解决这个问题,我添加了一个 curl 选项,您可以在请求中指定该选项,它将请求正文作为字符串发送,而不是从请求的实体正文中流式传输。您可以像这样启用此行为:

$options = $client->getConfig()->get('curl.options');
$options['body_as_string'] = TRUE;
$client->getConfig()->set('curl.options', $options);

【讨论】:

    【解决方案2】:

    我终于设法通过改变来完成这项工作

    'contents' => file_get_contents($file->path()),
    

    'contents' => \GuzzleHttp\Psr7\stream_for(fopen($file->path(), 'r'))
    

    有了这个更改,文件没有加载到内存中,我能够发送更大的文件

    【讨论】:

      猜你喜欢
      • 2018-06-27
      • 1970-01-01
      • 2014-02-22
      • 2011-05-18
      • 2020-12-01
      • 1970-01-01
      • 2023-02-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多