Публикация объектов JSON в Symfony 2

60

Я работаю над проектом с использованием Symfony 2, я создал пакет для обработки всех моих служб баз данных, которые передают данные JSON назад и вперед.

Моя проблема/вопрос:

  • Можно ли разместить прямо вверх объект JSON? В настоящее время я подменяю обычное сообщение формы для своих вызовов ajax, предоставляя объекту имя json={"key":"value"}, если я не даю ему имени. Я не могу получить данные из объекта запроса Symfony $JSON = $request->request->get('json');

  • Я хочу иметь возможность использовать один сервисный пакет для обработки как данных, поступающих из вызовов AJAX, так и обычной формы Symfony. В настоящее время я беру представленную форму Symfony, получая данные с помощью JSON_ENCODE, я просто не могу понять, как отправлять данные через мой диспетчер служб, который ожидает данные запроса.

Подводя итог:

  • Я хочу, чтобы Symfony принимал объект post JSON вместо формы.

  • Я хочу передать объект JSON между контроллерами, используя Request/Response

Если я все это сделаю неправильно, не стесняйтесь говорить мне об этом!

Теги:

3 ответа

111
Лучший ответ

Если вы хотите получить данные в контроллере, которые были отправлены стандартным JSON в тело запроса, вы можете сделать что-то похожее на следующее:

public function yourAction()
{
    $params = array();
    $content = $this->get("request")->getContent();
    if (!empty($content))
    {
        $params = json_decode($content, true); // 2nd param to get as array
    }
}

Теперь $params будет массивом, полным ваших данных JSON. Удалите значение параметра true в вызове json_decode(), чтобы получить объект stdClass.

  • 0
    Спасибо за ответ. Я действительно работал в выходные дни таким образом: $ JSON = file_get_contents ("php: // input"); Есть проблемы с этим?
  • 18
    php://input только для чтения. После того, как вы прочитали контент, он не будет доступен для чтения снова, если вы не передадите эти данные. Использование объекта запроса Symfony2 гарантирует, что вы можете получить данные снова во время запроса, если вам нужно, не передавая, например, вашу переменную $JSON .
Показать ещё 7 комментариев
6

Я написал метод для получения содержимого в виде массива

protected function getContentAsArray(Request $request){
    $content = $request->getContent();

    if(empty($content)){
        throw new BadRequestHttpException("Content is empty");
    }

    if(!Validator::isValidJsonString($content)){
        throw new BadRequestHttpException("Content is not a valid json");
    }

    return new ArrayCollection(json_decode($content, true));
}

И я использую этот метод, как показано ниже

$content = $this->getContentAsArray($request);
$category = new Category();
$category->setTitle($content->get('title'));
$category->setMetaTitle($content->get('meta_title'));
  • 1
    Класс валидатора существует по умолчанию в Symfony?
  • 0
    нет, это пользовательский класс
Показать ещё 2 комментария
1

javascript на странице:

function submitPostForm(url, data) {
    var form                = document.createElement("form");
        form.action         = url;
        form.method         = 'POST';
        form.style.display  = 'none';

    //if (typeof data === 'object') {}

    for (var attr in data) {
        var param       = document.createElement("input");
            param.name  = attr;
            param.value = data[attr];
            param.type  = 'hidden';
        form.appendChild(param);
    }

    document.body.appendChild(form);
    form.submit();
}

после некоторого события (например, щелчок на "отправить" ):

// products is now filled with a json array
var products = jQuery('#spreadSheetWidget').spreadsheet('getProducts');
var postData = {
'action':   action,
'products': products
}
submitPostForm(jQuery('#submitURLcreateorder').val(), postData);

в контроллере:

   /**
    * @Route("/varelager/bestilling", name="_varelager_bestilling")
    * @Template()
    */
   public function bestillingAction(Request $request) {
       $products   = $request->request->get('products', null); // json-string
       $action     = $request->request->get('action', null);

       return $this->render(
           'VarelagerBundle:Varelager:bestilling.html.twig',
           array(
               'postAction' => $action,
               'products' => $products
           )
       );
   }

в шаблоне (bestilling.html.twig в моем случае):

  {% block resources %}
       {{ parent() }}
       <script type="text/javascript">
       jQuery(function(){
           //jQuery('#placeDateWidget').placedate();
           {% autoescape false %}
           {% if products %}

           jQuery('#spreadSheetWidget').spreadsheet({
               enable_listitem_amount: 1,
               products: {{products}}
           });
           jQuery('#spreadSheetWidget').spreadsheet('sumQuantities');
           {% endif %}
           {% endautoescape %}

       });
       </script>
   {% endblock %}

Alrite, я думаю, что вы хотели:)

ИЗМЕНИТЬ Чтобы отправить что-то без симуляции формы, вы можете использовать jQuery.ajax(). Вот пример в том же духе, что и выше, что не приведет к обновлению страницы.

jQuery.ajax({
    url:        jQuery('#submitURLsaveorder').val(),
    data:       postData,
    success:    function(returnedData, textStatus, jqXHR ){
        jQuery('#spreadSheetWidget').spreadsheet('clear');
        window.alert("Bestillingen ble lagret");
        // consume returnedData here

    },
    error:      jQuery.varelager.ajaxError, // a method
    dataType:   'text',
    type:       'POST'
});
  • 0
    Спасибо за быстрый ответ! По сути, вы все еще отправляете нормальную форму с помощью javascript, это то, что я делаю в данный момент, мне было интересно, можно ли было напрямую публиковать объект JSON без симуляции формы, если не драмы. Кроме того, если у меня есть объект JSON в Symfony, можно ли отправить его другому сервису в качестве объекта запроса?
  • 0
    Я обратился к вашему комментарию в моем редактировании Я не совсем уверен, как делать Ajax без JQuery, так что я оставлю это вам. Чтобы отправить кого-то на другой контроллер, вы можете перенаправить его туда. Это описано в symfony.com/doc/2.0/book/controller.html в разделе Перенаправление и пересылка . Удачи!
Показать ещё 3 комментария
Сообщество Overcoder
Наверх
Меню