Я получил техническую поддержку от людей за API, которые я пытаюсь использовать, но они не хорошо разбираются в PHP и были менее полезными. Я подумал, что, возможно, я смогу помочь.
Я пытаюсь сделать запрос CURL через PHP. Технический парень говорит, что он использует следующую команду CURL через CLI, и она работает нормально:
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}
. Это не подходит для.jpg,.png и.gifs(.gif - это то, что использует технический парень). Я также попытался использовать как класс PHP CURLFile
и путь с @
в начале - оба получают ту же ошибку.
Как я уже сказал, опустив поле imageFile
и используя внешнюю стратегию, запрос работает очень хорошо, и версия CLI от технического парня также предположительно работает. Я пробовал как на своем локальном хосте, так и на реальном сервере, поэтому я предполагаю, что проблема связана с тем, как я отправляю файл.
Есть предположения? Дайте мне знать, если я должен добавить более подробную информацию.
ОБНОВЛЕНИЕ Я написал свой собственный скрипт, чтобы получить мой запрос, и он отлично отображает файл, что заставляет меня поверить в то, что это проблема в конце вендора. Будет продолжать обновляться.
ОБНОВЛЕНИЕ 2 Я не понял, что класс CURLFile не будет пытаться угадать тип MIME - вы должны явно передать его. Это была проблема. Взят под опеку.
Я не понимал, что класс CURLFile не будет пытаться угадать тип 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