Webservice通过curl命令行而不是PHP工作

时间:2015-11-26 22:46:53

标签: php web-services

我试图将curl命令翻译成我可以通过PHP运行的命令。

命令是:

curl -F customerid=902 -F username=API1 -F password=somepassword -F reportname=1002 http://somerandomurl.com/api/v1/getreportcsv

但是,当我尝试通过PHP(最终通过C#)运行时,Web服务会返回错误。知道我的代码出错可能是什么问题吗?我认为Web服务必须对头文件/请求非常具体:

$url = "http://somerandomurl.com/api/v1/getreportcsv";
$fields = [
  "customerid" => "902",
  "username"   => "API1",
  "password"   => "somepassword",
  "reportname" => "1002"
];

$fields_string = "";
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string,'&');

//open connection
$ch = curl_init();

curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);

//execute post
$result = curl_exec($ch);
print $result;

Wireshark显示以下差异:

以下是有效的:

POST /somefolder/api/v1/getreportcsv HTTP/1.1
Host: somehost
Accept: */*
Content-Length: 65
Content-Type: application/x-www-form-urlencoded

customerid=902&username=API1&password=somepassword&reportname=1002&HTTP/1.1 200 OK
Server: GlassFish Server Open Source Edition 3.1.1
Content-Type: text/html;charset=UTF-8
Content-Length: 6
Date: Thu, 26 Nov 2015 22:51:23 GMT

ERROR 

这个有效:

POST /someurl/api/v1/getreportcsv HTTP/1.1
User-Agent: curl/7.33.0
Host: somehost
Accept: */*
Content-Length: 459
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------4b0d14cc31a40c5b

HTTP/1.1 100 Continue

--------------------------4b0d14cc31a40c5b
Content-Disposition: form-data; name="customerid"

902
--------------------------4b0d14cc31a40c5b
Content-Disposition: form-data; name="username"

API1
--------------------------4b0d14cc31a40c5b
Content-Disposition: form-data; name="password"

somepassword
--------------------------4b0d14cc31a40c5b
Content-Disposition: form-data; name="reportname"

1002
--------------------------4b0d14cc31a40c5b--
HTTP/1.1 200 OK
Server: GlassFish Server Open Source Edition 3.1.1
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 26 Nov 2015 23:13:57 GMT

2000
...snip... the results of the api

显然他们是非常不同的要求,但是我不希望某些东西如此具体?

1 个答案:

答案 0 :(得分:1)

这个问题似乎对相关服务非常具体。

但是,问题可能出在标题上。根据{{​​3}}:

  

-F [...]使用Content-Type导致curl POST数据   根据RFC 2388

multipart/form-data

但是,根据curl man pageCURLOPT_POST选项将使用application/x-www-form-urlencoded发送数据。

根据同一手册,如果CURLOPT_POSTFIELDS的值是数组,则Content-Type标头将设置为multipart/form-data。您也可以尝试将内容类型明确设置为标题。

尝试设置以下cURL选项:

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: multipart/form-data'));

如果这不起作用,它可能有助于使用-v参数分析命令行curl发送的所有标头,并尝试设置它们。也可能是明智地设置内容长度标题。