Symfony2:从控制器回应JSON以在ExtJS 4网格中使用

Lev*_*ith 10 php model-view-controller json symfony extjs4

我刚刚开始使用Symfony2,我正在试图弄清楚从控制器(例如People)回显JSON 以用于ExtJS 4网格的正确方法.

当我使用vanilla MVC方法进行所有操作时,我的控制器会调用类似于getList调用People模型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']
        ));
    }
}
?>
Run Code Online (Sandbox Code Playgroud)
  • Symfony2中的这种行为是什么样的?
  • 控制器是否适合这种行为?
  • 解决此类问题的最佳实践(在Symfony中)是什么?

Mol*_*Man 12

控制器是否适合这种行为?

是.

Symfony2中的这种行为是什么样的?

解决此类问题的最佳实践(在Symfony中)是什么?

在symfony中它看起来非常相似,但有几个细微差别.

我想建议我对这些东西的方法.让我们从路由开始:

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

ScopeYourBundle_people_list:
    pattern:  /people
    defaults: { _controller: ScopeYourBundle:People:list, _format: json }
Run Code Online (Sandbox Code Playgroud)

_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
    )));
  }
  // ...
}    
Run Code Online (Sandbox Code Playgroud)

控制器以路由配置中设置的格式呈现数据.在我们的例子中,它是json格式.

以下是可能模板的示例:

{# app/Resourses/views/base.json.twig #}
{{ data | json_encode | raw }}
Run Code Online (Sandbox Code Playgroud)

这种方法的优点(我的意思是使用_format)就是如果你决定从json切换到例如xml而不是没有问题 - 只需在路由配置中替换_format,当然,创建相应的模板.


Tob*_*tch 8

我会避免使用模板来呈现数据,因为然后在模板中负责转义数据等.相反,我在PHP中使用内置的json_encode函数,就像你建议的那样.

按照上一个答案中的建议,在routing.yml中设置到控制器的路由:

ScopeYourBundle_people_list:
pattern:  /people
defaults: { _controller: ScopeYourBundle:People:list, _format: json }
Run Code Online (Sandbox Code Playgroud)

唯一的额外步骤是强制响应中的编码.

<?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;
    }
}
?>
Run Code Online (Sandbox Code Playgroud)

  • 只是一个小小的注意事项,如果路由正确指定`_format`选项,那么`Content-Type`标头由Symfony2自动设置,因为它可以在`Response`类[here](https:// github)中看到. COM/symfony的/ symfony的/斑点/主/ SRC/Symfony的/组件/ HttpFoundation/Response.php#L166).因为在这个例子中,格式是`json`,所以带有值''application/json'`的`Content-Type`标题将被附加到响应中. (2认同)