Symfony2: вывод JSON из контроллера для использования в сетке ExtJS 4 - PullRequest
10 голосов
/ 05 февраля 2012

Я только начинаю работать с Symfony2 и пытаюсь выяснить, каков правильный подход для вывода JSON из контроллера (например, People) для использования в сетке ExtJS 4.

Когда я делал все, используя ванильный подход MVC, мой контроллер имел метод, называемый getList, который вызывал бы метод People модели *1005*, принимал эти результаты и делал что-то вроде этого:

<?php
class PeopleController extends controller {
    public function getList() {
        $model = new People();
        $data = $model->getList();
        echo json_encode(array(
            'success' => true,
            'root' => 'people',
            'rows' => $data['rows'],
            'count' => $data['count']
        ));
    }
}
?>
  • Как выглядит такое поведение в Symfony2?
  • Является ли контроллер подходящим местом для такого поведения?
  • Каковы лучшие практики (в рамкахSymfony) для решения такого рода проблем?

Ответы [ 6 ]

12 голосов
/ 05 февраля 2012

Является ли контроллер подходящим местом для такого поведения?

Да.

Как выглядит такое поведение в Symfony2?

Каковы лучшие практики (в Symfony) для решения такого рода проблем?

В Symfony это выглядит примерно одинаково, но есть пара нюансов.

Я хочу предложить свой подход к этому материалу. Начнем с маршрутизации:

# src/Scope/YourBundle/Resources/config/routing.yml

ScopeYourBundle_people_list:
    pattern:  /people
    defaults: { _controller: ScopeYourBundle:People:list, _format: json }

Параметр _format не обязателен, но позже вы поймете, почему он важен.

Теперь давайте посмотрим на контроллер

<?php
// src/Scope/YourBundle/Controller/PeopleController.php
namespace Overseer\MainBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 

class PeopleController extends Controller
{   
  public function listAction()
  {
    $request = $this->getRequest();

    // if ajax only is going to be used uncomment next lines
    //if (!$request->isXmlHttpRequest())
      //throw $this->createNotFoundException('The page is not found');

    $repository = $this->getDoctrine()
          ->getRepository('ScopeYourBundle:People');

    // now you have to retrieve data from people repository.
    // If the following code looks unfamiliar read http://symfony.com/doc/current/book/doctrine.html
    $items = $repository->findAll();
    // or you can use something more sophisticated:
    $items = $repository->findPage($request->query->get('page'), $request->query->get('limit'));
    // the line above would work provided you have created "findPage" function in your repository

    // yes, here we are retrieving "_format" from routing. In our case it's json
    $format = $request->getRequestFormat();

    return $this->render('::base.'.$format.'.twig', array('data' => array(
      'success' => true,
      'rows' => $items,
      // and so on
    )));
  }
  // ...
}    

Контроллер отображает данные в формате, заданном в конфигурации маршрутизации. В нашем случае это формат json.

Вот пример возможного шаблона:

{# app/Resourses/views/base.json.twig #}
{{ data | json_encode | raw }}

Преимущество этого подхода (я имею в виду использование _format) состоит в том, что если вы решите переключиться с json, например, на xml, то это не проблема - просто замените _format в конфигурации маршрутизации и, конечно, создайте соответствующий шаблон. 1029 *

8 голосов
/ 05 февраля 2012

Я бы не использовал шаблон для отображения данных, так как ответственность за экранирование данных и т. Д. В этом случае лежит на шаблоне. Вместо этого я использую встроенную функцию json_encode в PHP, как вы и предлагали.

Установите маршрут к контроллеру в routing.yml, как предложено в предыдущем ответе:

ScopeYourBundle_people_list:
pattern:  /people
defaults: { _controller: ScopeYourBundle:People:list, _format: json }

Единственный дополнительный шаг - принудительное кодирование в ответе.

<?php
class PeopleController extends controller {
    public function listAction() {
        $model = new People();
        $data = $model->getList();
        $data = array(
            'success' => true,
            'root' => 'people',
            'rows' => $data['rows'],
            'count' => $data['count']
        );
        $response = new \Symfony\Component\HttpFoundation\Response(json_encode($data));
        $response->headers->set('Content-Type', 'application/json');
        return $response;
    }
}
?>
1 голос
/ 20 февраля 2015

Вместо создания собственного ответа вы также можете использовать встроенный JsonResponse .

Вы определяете маршрут, как в других предложенных ответах:

ScopeYourBundle_people_list:
pattern:  /people
defaults: { _controller: ScopeYourBundle:People:list, _format: json }

И используйте новый тип ответа:

<?php
class PeopleController extends controller {
    public function listAction() {
        $model = new People();
        $data = $model->getList();
        $data = array(
            'success' => true,
            'root' => 'people',
            'rows' => $data['rows'],
            'count' => $data['count']
        );
        return new \Symfony\Component\HttpFoundation\JsonResponse($data);
    }
}

Для получения дополнительной информации см. api или doc (версия 2.6).

1 голос
/ 05 декабря 2013

Для использования return new JsonResponse(array('a' => 'value', 'b' => 'another-value'); необходимо использовать правильное пространство имен:

use Symfony\Component\HttpFoundation\JsonResponse;

Как описано здесь: http://symfony.com/doc/current/components/http_foundation/introduction.html#creating-a-json-response

0 голосов
/ 14 августа 2013

использование

    return JsonResponse($data, StatusCode, Headers);
0 голосов
/ 29 мая 2013

Simple. Используйте FOSRestBundle и возвращайте только объект People из контроллера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...