PHP + CURL - commonsMultipartFile 错误?

PHP + CURL - commonsMultipartFile error?

我已经从我正在尝试使用的 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,我可以发出类似的请求,但我没有发送 imageFile,而是简单地发送了 URL 图像所在的位置,服务使用外部托管的图像。通过添加 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 class 和开头带有 @ 的路径 - 两者都得到相同的错误。

就像我说的,通过省略 imageFile 字段并使用外部托管策略,请求工作得很好,技术人员的 CLI 版本也应该工作。我在本地主机和实时服务器上都试过了,所以我认为问题出在我发送文件的方式上。

有什么想法吗?让我知道是否应该添加更多详细信息。

更新 我编写了自己的脚本来接收我的请求,它得到的文件很好,这让我相信这是供应商端的问题。会继续更新的。

更新 2 我没有意识到 CURLFile class 不会尝试猜测 MIME 类型 - 您必须显式传递它。这就是问题所在。照顾好。

我将它用于我所有的 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

我没有意识到 CURLFile class 不会尝试猜测 MIME 类型 - 您必须明确传递它。这就是问题所在。照顾好了。