Отправка файла с POST-запросом через Drupal API
Сколько же я времени потратил, когда впервые столкнулся с этой задачей! И каково же было мое удивление, что Drupal из коробки, к сожалению, не имеет API для передачи файлов в POST-запросах – все заголовки и параметры запроса надо описывать самому.
Drupal имеет в своем арсенале API функцию , через которую по-хорошему и стоит осуществлять все запросы к внешним сервисам. Однако для отправки файла придется немного разобраться с параметрами этой функции. Допустим, у нас есть путь к файлу, который мы хотим отправить вместе с POST-запросом. Основная функция будет выглядеть так:drupal_http_request()
- /**
 -  * Sends file to service.
 -  *
 -  * @param $path
 -  */
 - function fileUpload($path) {
 -   $params = array(
 -     // Указываем необходимые данные для передачи с запросом.
 -     'data' => '123',
 -   );
 -  
 -   $boundary = md5(uniqid());
 -   $post_data = array(
 -     'name' => basename($path),
 -     'file' => $path,
 -   );
 -  
 -   $options = array(
 -     'method' => 'POST',
 -     'data' => multipartEncode($boundary, $post_data),
 -     'headers' => array('Content-Type' => "multipart/form-data; boundary=$boundary"),
 -     'timeout' => 30,
 -   );
 -  
 -   $response = drupal_http_request('http://path/to/service' . '?' . drupal_http_build_query($params), $options);
 -  
 -   return $response;
 - }
 
Формирование данных для отправки файла в POST
Теперь несколько вспомогательных функций, которые помогут закодировать данные файла в нужном формате для отправки.
- /**
 -  * Processes data for HTTP request.
 -  *
 -  * @param $boundary
 -  * @param $params
 -  */
 - function multipartEncode($boundary, $params){
 -   $output = "";
 -  
 -   foreach ($params as $key => $value){
 -     $output .= "--$boundary\r\n";
 -     if ($key == 'file'){
 -       $output .= multipartEncFile($value);
 -     } else {
 -       $output .= multipartEncText($key, $value);
 -     }
 -   }
 -   $output .="--$boundary--";
 -  
 -   return $output;
 - }
 -  
 - /**
 -  * Encodes text for HTTP request.
 -  *
 -  * @param $name
 -  * @param $value
 -  */
 - function multipartEncText($name, $value){
 -   return "Content-Disposition: form-data; name=\"$name\"\r\n\r\n$value\r\n";
 - }
 -  
 - /**
 -  * Encodes file data for HTTP request.
 -  *
 -  * @param $path
 -  */
 - function multipartEncFile($path){
 -   if (substr($path, 0, 1) == "@") {
 -     $path = substr($path, 1);
 -   }
 -   $filename = basename($path);
 -   $mimetype = "application/octet-stream";
 -   $data = "Content-Disposition: form-data; name=\"file\"; filename=\"$filename\"\r\n";
 -   $data .= "Content-Transfer-Encoding: binary\r\n";
 -   $data .= "Content-Type: $mimetype\r\n\r\n";
 -   $data .= file_get_contents($path) . "\r\n";
 -  
 -   return $data;
 - }
 
Да, код не претендует на гениальность и соответствие стандартам кодирования. Я сам, признаюсь, пока еще не вникал в тонкости его работы, но он у меня работает – а это главное. Это как-нибудь потом разберусь, как будет свободное время, что значит каждый параметр и строчка в функциях кодирования данных файла для передачи c POST-запросом.
              
              
Комментарии
Подскажите, а как сделать обратное действие, то есть отправить запрос на получение файла (.txt) и получить его?
Добавить комментарий