Категория:
Опубликовано:

Простой способ прочитать данные из POST запроса

Drupal - Simple REST:API

Для полноценных аппликух, конечно лучше организовывать RESTful-сервер, но иногда необходимо просто, периодически, принимать данные со стороннего сервиса.

В таких случаях можно организовать процесс многим проще. И вот как:

В коллбеке хука меню, данные из POST запроса можно получить из потока входящих данных - php://input.

По-сути, нужно считать поток с текущей страницы в переменную.

Рассмотрим пример с получением данных приходящих в JSON-формате:

/**
 * Implements hook_menu().
 */
function MYMODULE_menu() {
  $items['mymodule_get_json'] = array(
    'page callback'    => 'mymodule_get_json',
    'type'             => MENU_CALLBACK,
  );

  return $items;
}

/**
 * My custom page callback
 */
function mymodule_get_json() {
  // Получаем данные из запроса
  $post = file_get_contents("php://input",  TRUE);

  // Если данные есть - работаем с ними
  if ($post) {
    // Декодим JSON в PHP-массив
    $json = drupal_json_decode($post);
    
    // Далее, производим манипуляции с пришедшими данными
  }

  return array();
}

Так можно, достаточно просто, обработать входящие данные.

И, хоть у нас и не полноценное RESTful-приложение, тем не менее, хорошей практикой будет оповестить машину отправляющую нам POST-запрос об успехе или неудаче.

В таких случаях, нам пригодятся следующие инструменты:

  • drupal_add_http_header (для формирования заголовков)
  • drupal_json_encode - для конвертации данных в JSON (если мы работаем с этим форматом)

Также, не забываем что нужен не рендеринг страницы, а вывод (печать) ответа.

Потому, меняем возврат на вывод и выходим (расписываю подробно, для понимания процессов - ниже, представлю упрощенную версию):

/**
 * My custom page callback
 */
function mymodule_get_json() {
  $post = file_get_contents("php://input", TRUE);

  if ($post) {
    $json = drupal_json_decode($post);

    // Обработаем данные и вернем результат обработки
    $result = mymodule_some_processing_function($json);

    // Добавляем в заголовки тип данных
    drupal_add_http_header('Content-Type', 'application/json');

    // Если все прошло удачно - отвечаем успехом
    if ($result['status'] == TRUE) {
      $output = array(
        'status'  => 'success',
        'message' => t('Everything is alright'),
      );
    }
    // Если что-то пошло не так - вернем ошибку с описанием
    else {
      $output = array(
        'status'  => 'error',
        'message' => t('Something went wrong'),
        // Также, желательно указывать код ошибки
        'code'    => 0,
      );
    }

    // Конвертируем данные в JSON
    echo drupal_json_encode($output);
    // Подготавливаем все процессы для завершения
    module_invoke_all('exit');
    // И выходим (хардово)
    exit();
  }
  else {
    // Если данных нет - запрещаем доступ
    drupal_access_denied();
  }
}

Но, более правильно, воспользоваться готовыми средствами:

  • drupal_json_output данная ф-ция проделывает за нас все, для выдачи JSON'а (добавляет хедеры, энкодит и выводит данные на страницу)
  • drupal_exit - завершает все процессы, с необходимыми проверками

Так получается гораздо лаконичнее:

/**
 * My custom page callback
 */
function mymodule_get_json() {
  $post = file_get_contents("php://input", TRUE);

  if ($post) {
    $json = drupal_json_decode($post);
    $result = mymodule_some_processing_function($json);

    if ($result['status'] == TRUE) {
      $output = array(
        'status'  => 'success',
        'message' => $result['message'],
      );
    }
    else {
      $output = array(
        'status'  => 'error',
        'message' => $result['message'],
        'code'    => $result['code'],
      );
    }

    drupal_json_output($output);
    drupal_exit();
  }
  else {
    drupal_access_denied();
  }
}

Успехов!

Теги: 
Если у Вас возникли вопросы, замечания, предложения или просто благодарность - пишите в комментариях.
Делитесь полезными материалами в социальных сетях.