使用Guzzle重写curl(文件上传)- PHP

3

我正在尝试将文件上传到我的服务器,然后将该文件发送到Zendesk。Zendesk文档展示了如何实现:

curl "https://{subdomain}.zendesk.com/api/v2/uploads.json?filename=myfile.dat&token={optional_token}" \
  -v -u {email_address}:{password} \
  -H "Content-Type: application/binary" \
  --data-binary @file.dat -X POST

这个很好用。现在我需要使用Guzzle(版本6)重写它。 我正在使用Symfony 2.7:

$file = $request->files->get('file');

$urlAttachments = $this->params['base_url']."/api/v2/uploads.json?filename=".$file->getClientOriginalName();

$body = [
        'auth' => [$this->params['user'], $this->params['pass']],
        'multipart' => [
        [
            'name'     => $archivo->getClientOriginalName(),
            'contents' => fopen($file->getRealPath(), "r"),
        ],
    ]
];

$client = new \GuzzleHttp\Client();
$response = $client->request('POST', $urlAttachments, $body);
$response = json_decode($response->getBody(), true);

文件正在上传,但是当我下载它时,它的内容中也包含了一些元数据(破坏了其他文件类型)。我想我可能没有正确地上传它,因为使用curl命令上传可以正常工作。
--5b8003c370f19
Content-Disposition: form-data; name="test.txt"; filename="php6wiix1"
Content-Length: 1040

... The rest of the original content of the test file...

--5b8003c370f19--

我不知道为什么这些数据也被发送到文件中(我不想要它),或者使用multipart是否可以。

感谢任何帮助!

1个回答

9

可以使用 multipart,但服务器必须正确处理它。无论是否使用它,请求正文都是不同的。

它经常用于具有(多个)文件上传的HTML表单中。文件被命名(因此是元信息),因此可能有多个文件。除了文件之外,还可以有普通表单字段(文本)。您可以在搜索中找到更好的解释,我只想简要说明一下。

而且,在您的情况下,服务器似乎没有将multipart表单数据与“二进制发布”区别对待,因此它会保存全部内容,包括元信息。

使用body传递原始正文,并使用Guzzle生成完全相同的请求:

$urlAttachments = $this->params['base_url']."/api/v2/uploads.json?filename=".$file->getClientOriginalName();

$opts = [
    // auth
    'body' => fopen($file->getRealPath(), "r"),
    'headers' => ['Content-Type' => 'application/binary'],
];

$client = new \GuzzleHttp\Client();
$response = $client->request('POST', $urlAttachments, $opts);

太好了!这个方法起作用了!我还得增加nginx和php-fpm的上传大小。谢谢! - monstercode

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接