Symfony2: повторение JSON от контроллера для использования в сетке ExtJS 4

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

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

 <?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) для решения этой проблемы?

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

Да.

Как выглядит это поведение в 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 в конфигурации маршрутизации и, конечно же, создайте соответствующий шаблон.

Я бы не использовал шаблон для визуализации данных, так как ответственность за экранирование данных и т. Д. Затем находится в шаблоне. Вместо этого я использую встроенную функцию 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; } } ?> 

Чтобы использовать 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

Вместо создания собственного ответа вы также можете использовать встроенный 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).

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

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

  return JsonResponse($data, StatusCode, Headers);