PHP + CURL - commonsMultipartFile错误?

时间:2015-02-19 15:15:31

标签: php curl

我已经获得了我试图利用的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类型 - 你必须明确地传递它。那就是问题所在。照顾。

2 个答案:

答案 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类型 - 你必须明确地传递它。那就是问题所在。照顾。