Как отправить запрос PUT с файлом и массивом данных с помощью PHP

Я настроил службу и клиент REST на PHP, и у меня возникли проблемы с PUT.

Вот моя ситуация: я кодирую ресурс REST, который должен принимать массив данных и изображение. Ресурс REST должен обновить существующую запись, поэтому я использую PUT. Я отправляю данные с помощью написанного мной PHP curl-клиента. Итак - почти такая же ситуация, как если бы вы отправляли составную HTML-форму в PHP-скрипт, который выполняет загрузку файла и принимает некоторые дополнительные поля POST - за исключением PUT и PHP curl ..

До сих пор я отправлял запрос PUT примерно так (псевдокод):

$a_some_data = array('name' => 'test', 'user_id' => 4);
$body = http_build_query($a_data);

$fh = fopen('php://memory', 'rw');
fwrite($body);
rewind($fh);

$ch = curl_init();
curl_setopt_array($ch, array(
  CURLOPT_URL => 'http://myapi/resource/someid',
  CURLOPT_PUT => TRUE,
  CURLOPT_INFILE => $fh,
  CURLOPT_INFILESIZE => strlen($body)
  ));
curl_exec($ch);

и читаем данные на сервере так:

parse_str(file_get_contents('php://input'), $put_data);

..который отлично работает.

Итак, теперь я хотел бы добавить в микс (бинарный) файл. - Как бы это реализовать на стороне клиента? - Как бы мне поступить с файлом на сервере?

Для теста я создал HTML-форму с вводом файла, скопировал необработанный запрос multipart / form-data, который он отправляет, и попытался отправить эти данные в виде файла с помощью curl в запросе PUT. Это работает, но мне пришлось бы вручную анализировать необработанные данные на сервере, что, я не уверен, является лучшей идеей. В качестве альтернативы, я думаю, я мог бы отправить файл как тело запроса PUT и добавить другие параметры в URL-адрес в виде строки запроса - но я полагаю, что такой вид не соответствует сути ресурса PUT REST ..

Пожалуйста, поделитесь своими мыслями по этому поводу. Спасибо!


person Christof    schedule 29.03.2011    source источник


Ответы (1)


Есть по крайней мере два других способа, если вашей исходной версии недостаточно (поскольку libcurl также должен отлично справляться с двоичными файлами с этим сценарием). Обратите внимание, что то, как вы решите получить PUT на принимающей стороне, не является проблемой скручивания, поэтому я оставлю ее в этом ответе.

1 - Как вы начали, но предоставьте CURLOPT_READFUNCTION, с помощью которого вы передаете данные в libcurl, которые он будет отправлять.

2 - Используйте CURLOPT_POSTFIELDS (со строкой) и сделайте его похожим на POST, а затем вы измените метод HTTP с помощью CURLOPT_CUSTOMREQUEST на «PUT»

person Daniel Stenberg    schedule 29.03.2011
comment
Спасибо, Даниэль. Мне нравится вторая версия, похоже, так и есть - поскольку запрос по-прежнему отправляется как PUT, но с составным содержимым. Теперь данные, которые я получаю на сервере во вводе php: //, в значительной степени соответствуют тому, что я получил бы, если бы отправил все с помощью HTML-формы. Вы знаете, как лучше всего это разобрать? Есть ли хороший способ извлечь данные и файл из этих необработанных данных или мне нужно проанализировать их вручную? - person Christof; 30.03.2011