Как установить несколько типов контента? - PullRequest
1 голос
/ 22 декабря 2011

Как установить несколько типов контента? Я должен передать массив для запроса тела. Этот массив содержит текст и изображение в двоичном виде.

curl_setopt($apiCon, CURLOPT_POSTFIELDS, array(
    'status' => rawurlencode($status), 
    'photo' => $photoInBinary
));
curl_setopt($apiCon, CURLOPT_HTTPHEADER, array(
    'Host: api.mixi-platform.com', 
    'Authorization: OAuth ' . $accessToken, 
    'Content-Type: multipart/form-data'
));

Проблема в том, что хост не понимает формат изображения, поэтому мне нужно передать больше контента типа 'image / jpg', но я не знаю, где его разместить.

Приведенный выше код работает, но он публикует только статус.

Обновление: Хорошо, моя цель - опубликовать статус с фотографией на странице социальной сети.

Для получения дополнительной информации прочитайте это: http://developer.mixi.co.jp/en/connect/mixi_graph_api/mixi_io_spec_top/voice-api/#toc-10

Это мой код. Работает, но публикует только статус, а не фото.

    $apiCon = curl_init(self::API_POST_STATUS_WITH_PHOTO);
    curl_setopt($apiCon, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($apiCon, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($apiCon, CURLOPT_POST, true);
    curl_setopt($apiCon, CURLOPT_POSTFIELDS, array('status' => rawurlencode($status), 'photo' => $photoInBinary));
    curl_setopt($apiCon, CURLOPT_HTTPHEADER, array('Host: api.mixi-platform.com', 'Authorization: OAuth ' . $accessToken, 'Content-Type: multipart/form-data'));
    $result = curl_exec($apiCon);        
    curl_close($apiCon);

1 Ответ

1 голос
/ 22 декабря 2011

Сначала попробуйте не кодировать свое поле состояния (т.е. удалить rawurlencode). Это двойное кодирование, и, возможно, именно поэтому ваш хост жалуется.

(Кроме того, вам не нужно явно устанавливать заголовок типа содержимого; CURL сделает это.)

Если этого недостаточно, вам нужно либо изменить порядок запроса, чтобы использовать магический механизм выгрузки файлов CURL, либо вы сами должны создать всю строку multipart / form-data.

Вот как работает механизм магического файла CURL (из документации до CURLOPT_POSTFIELDS:

Полные данные для отправки в HTTP-операции «POST». Чтобы опубликовать файл, добавьте @ к имени файла и используйте полный путь. Тип файла можно явно указать, следуя имени файла с типом в формате '; type = mimetype'. Этот параметр может быть передан в виде строки в кодировке urlen, например, 'para1 = val1 & para2 = val2 & ...', или в виде массива с именем поля в качестве ключа и данными поля в качестве значения. Если значение является массивом, заголовок Content-Type будет установлен в multipart / form-data. Начиная с PHP 5.2.0 значение должно быть массивом, если файлы передаются этой опции с префиксом @.

Единственный способ передать тип содержимого определенного поля в POST multipart / form-data с использованием CURL - использовать следующий синтаксис для значения поля: @filepath;type=mime/type.

Если ваш $photoInBinary начал жизнь в файле, просто передайте имя файла в вышеуказанном формате CURL вместо открытия файла и чтения данных.

Однако, , если вы сами создали фотографию в памяти, вам нужно записать ее во временный файл . Вот как вы можете это сделать:

function curlFileUploadData($data, $type='') {
    // $data can be a string or a stream
    $filename = tempnam(sys_get_temp_dir(), 'curlupload-');
    file_put_contents($filename, $data);
    $curlparam = "@{$filename}";
    if ($type) {
        $curlparam .= ";type={$type}";
    }
    return array($curlparam, $filename);
}

list($curlparam, $tmpfile) = curlFileUploadData('thedata', 'image/bmp');

// You can see the raw bits CURL sends if you run 'nc -l 9999' at a command line first
$c = curl_init('http://localhost:9999');
curl_setopt($c, CURLOPT_POSTFIELDS, array('status' => 'good', 'photo' => $curlparam));
curl_exec($c);
curl_close($c);

unlink($tmpfile); // REMEMBER TO DO THIS!!!!

Обратите внимание, что CURL установит параметр имени файла при загрузке файла из нескольких частей. Убедитесь, что хост не использует это ни для чего важного. Насколько я знаю, нет способа переопределить имя файла, отправляемое CURL - оно всегда будет именно тем, что было дано.

Если вы не хотите создавать временный файл и должны использовать CURL, вам нужно будет создать все тело multipart / form-data в виде строки в памяти и передать ее в CURL в виде строки CURL_POSTFIELDS и вручную установите заголовок типа содержимого на multipart/form-data. Это оставлено в качестве упражнения для читателя. К этому времени вам следует рассмотреть возможность использования вместо HTTP-расширения или даже fopen с stream_context_create() для установки метода http и заголовков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...