Отправка файла с 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) и получить его?
Добавить комментарий