Php Zend_Http_客户端-为什么我的POST请求发送了错误的内容类型头?

Php Zend_Http_客户端-为什么我的POST请求发送了错误的内容类型头?,php,zend-framework,zend-http-client,Php,Zend Framework,Zend Http Client,我正在使用Zend Http客户端调用外部服务。该服务允许我将文件上传到他们的存储系统。它要求在查询字符串中发送相关参数(userid等),文件上传内容应在帖子正文中发送,内容类型为“application/zip”(我将发送一个包含各种内容的zip文件) 为此,我使用zend客户端的setParameterGet()函数在查询字符串中设置参数。然后,我使用setFileUpload()函数设置文件上载内容: $this->client->setFileUpload($zipFile

我正在使用Zend Http客户端调用外部服务。该服务允许我将文件上传到他们的存储系统。它要求在查询字符串中发送相关参数(userid等),文件上传内容应在帖子正文中发送,内容类型为“application/zip”(我将发送一个包含各种内容的zip文件)

为此,我使用zend客户端的setParameterGet()函数在查询字符串中设置参数。然后,我使用setFileUpload()函数设置文件上载内容:

$this->client->setFileUpload($zipFilePath, 'content', null, 'application/zip');
但是,服务告诉我,我发送的内容类型是错误的,即“多部分/表单数据”

以下是Zend客户端发送给服务的原始头(请注意,我已经删除了一些敏感信息,将它们替换为[]括号中的项目名称)

职位 https://[ServiceURL]?cmd=[COMMAND]&enrollmentid=[enrollmentid]&itemid=[itemid]

HTTP/1.1

主机:[Host]接受编码:gzip,deflate

用户代理:Zend_Http_客户端Cookie:

AZT=9cMFAIBgG-eM1K | Bw7Qxlw7pBuPJwm0PCHryD

内容类型:多部分/表单数据;边界=---ZENDHTTPCLIENT-05535ba63b5130ab41d9c75859f678d8

内容长度:2967

-----ZENDHTTPCLIENT-05535ba63b5130ab41d9c75859f678d8

内容配置:表单数据;name=“content”; filename=“agilixContent.zip”

内容类型:应用程序/zip

[此处为原始文件数据]


因此,基本上,即使我设置了POST内容类型头,我的外部服务也会告诉我发送了错误的内容类型,因为还有另一个内容类型头的值为“multipart/form data”。我已尝试更改/删除该内容标题,但无效如何删除该标头,以便我的请求中不会出现这两个重复的“内容类型”标头?

我不确定您如何使用Zend HTTP Client做到这一点,但我相信您可以使用plain cURL做到这一点。正如您一定知道的,cURL给了您很多灵活性,我还没有深入讨论Zend,但是Zend可能在内部使用cURL

<?php

// URL on which we have to post data
$url = "http://localhost/tutorials/post.php";
// Any other field you might want to catch
$post_data = "khan";
// File you want to upload/post
//$post_data['zip_file'] = "@c:/foobar.zip";

$headers[] = "Content-Type: application/zip";

// Initialize cURL
$ch = curl_init();
// Set URL on which you want to post the Form and/or data
curl_setopt($ch, CURLOPT_URL, $url);
// Data+Files to be posted
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
// Set any custom header you may want to set or override defaults
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 
// Pass TRUE or 1 if you want to wait for and catch the response against the request made
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// For Debug mode; shows up any error encountered during the operation
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Execute the request
$response = curl_exec($ch);

// Just for debug: to see response
echo $response;

如果您想使用“application/zip”作为内容类型上载文件,则不应使用
->setFileUpload()
,而应使用
->setRawData()
setFileUpload()
用于模拟基于HTML表单的文件上载,这不是您所需要的

有关更多信息,请参阅。您需要的(基于您最初的示例)是:

$zipFileData = file_get_contents($zipFilePath);
$this->client->setRawData($zipFileData, 'application/zip');
$response = $this->client->request('POST');

请注意,如果您的ZIP文件可能非常大(比如超过几兆字节),您可能希望使用ZHC的流媒体支持功能,因此避免占用内存。如果你知道你的文件总是小于5-10兆字节,我就不必麻烦了

我正在查看HTTP_客户端()的ZF API,您是否尝试过使用“setEncType(string$enctype)”,setFileUpload的API是:“setFileUpload(string$filename,string$formname,string$data=null,string$ctype=null)”,我必须进行一些挖掘,但它可能不是实际设置整个头编码的API。我正在翻阅参考指南,看看是否有任何帮助。在我提出请求之前,我只是尝试使用setEncType('application/zip'),但标题并没有保持不变。第一个仍然是“multipart/formdata”,而第二个是“application/zip”。谢谢你的建议,我还没有想到要尝试这个功能。:)隐马尔可夫模型。。。我正在深入研究ZF代码(Zend/Http/Client.php),我正在查找
multipart/form data
,我看到了
setFileUpload()
函数的以下注释
Force enctype to multipart/form data
。这包括
\u prepareBody()
如果我们有文件要上传,请强制enctype到多部分/表单数据。长话短说,ZF_Http_客户端似乎不允许您将整个数据包内容类型设置为
application/zip
。我可能有一个很好的理由,但这可能是因为zip是一个附件,而不仅仅是一个文件。如果您想覆盖它,请创建一个新类并扩展客户端类并覆盖该代码位以允许。不过,我不得不声明,我不确定这是否是一个好建议,因为我对HTTP协议不够熟悉。感谢您了解使用setFileUpload时客户端强制使用多部分/表单数据的情况!我做了一些测试,结果证明这是我的问题。我没有使用setFileUpload,而是尝试使用setHeaders('Content-Type','application/zip')和setRawData()来发送zip文件内容,“multipart/form data”头不再随请求一起发送。服务现在正常工作,有了这个变化。非常感谢!仅供参考,我在本地机器上测试了上述代码,并获得了预期的内容类型的正确标题。是的,这就是问题所在。:)我没有意识到setFileUpload是在模仿上传表单字段。setRawData很好地完成了这个任务。