我已经获得了我试图利用的API背后的人们的技术支持,但他们并不精通PHP并且不太有帮助。我想也许我可以在这里得到一些帮助。
我试图通过PHP发出CURL请求。技术人员说他正在通过CLI使用以下CURL命令,它工作得很好:
curl -X POST -k -H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" -F "hash=a0fbb9f14e6965300d6736f65cd98e82" -F "timestamp=1424088034782" -F "username=David" -F "placementType=SITE_PLACEMENT" -F "campaignId=333" -F "active=true" -F "name=complex" -F "weight=1" -F "adUnitId=1" -F "bannerType=LOCAL_FILE" -F "imageFile=@c:/scripts/1.gif" -F "url=http://qwe.com" -F "imageBannerLink=http://qwe.com" "https://theapi.com/create.do"
大多数这些领域并不重要。通过PHP,我可以发出类似的请求,但我只是发送图像所在的URL而不是发送imageFile,而服务使用外部托管的图像。通过添加imageFile
参数,服务应该创建图像的本地副本并将其保存在那里,这是目标。因此,这是唯一一个在工作示例和非工作示例之间变化的字段。
所以,我现在的PHP代码不起作用:
$local_file_absolute = realpath($local_file);
$cfile = new CURLFile($local_file_absolute); //cfile is valid, I've checked
$creative_fields = array();
//...add all the fields that are fine because they work for the external hosting strategy, match those in the given CLI CURL request...//
$creative_fields['imageFile'] = $cfile;
$ch = curl_init('https://theapi.com/create.do);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $creative_fields);
$verbose = fopen('php://temp', 'rw+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);
$response = curl_exec($ch);
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
echo "Verbose information:\n<pre>", htmlspecialchars($verboseLog), "</pre>\n";
我的详细日志在接收服务器上显示{400}错误HTTP Status 400 - {commonsMultipartFile=must be image or flash file}
。这对于.jpgs,.pngs和.gifs(.gif是技术人员正在使用的)失败了。我也尝试过使用PHP CURLFile
类和开头的@
路径 - 都会得到同样的错误。
就像我说的那样,通过省略imageFile
字段并使用外部托管策略,请求工作正常,而技术人员的CLI版本也可以正常工作。我已尝试过本地主机和实时服务器,因此我认为问题在于我如何发送文件。
有什么想法?如果我要添加更多细节,请告诉我。
更新 我编写了自己的脚本来接收我的请求,它使文件很好,这让我相信这是供应商的问题。将继续更新。
更新2 我没有意识到CURLFile类不会尝试猜测MIME类型 - 你必须明确地传递它。那就是问题所在。照顾。
答案 0 :(得分:0)
我将这个用于所有CURL操作,并且没有任何问题(除了调整结果格式):
$ch = curl_init("url here");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_TIMEOUT, 60);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
$result=curl_exec ($ch);
echo '<!-- '. $result. ' -->'; // THIS LINE IS FOR DEBUG PURPOSES ONLY-IT WILL SHOW IN HTML COMMENTS
$data=strstr($result,'<');
$xml_parser = xml_parser_create();
xml_parse_into_struct($xml_parser, $data, $vals, $index);
xml_parser_free($xml_parser);
$params = array();
$level = array();
foreach ($vals as $xml_elem) {
if ($xml_elem['type'] == 'open') {
if (array_key_exists('attributes',$xml_elem)) {
list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
} else {
$level[$xml_elem['level']] = $xml_elem['tag'];
}
}
if ($xml_elem['type'] == 'complete') {
$start_level = 1;
$php_stmt = '$params';
while($start_level < $xml_elem['level']) {
$php_stmt .= '[$level['.$start_level.']]';
$start_level++;
}
$php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
if(isset($xml_elem['value']))
eval($php_stmt);
}
}
curl_close($ch);
return $params;
编辑:
显然将你的xml查询或w / e放在$ data
中答案 1 :(得分:0)
我没有意识到CURLFile类不会尝试猜测MIME类型 - 你必须明确地传递它。那就是问题所在。照顾。