【问题标题】:Symfony2: Echoing JSON From a Controller for Use in an ExtJS 4 GridSymfony2:从控制器中回显 JSON 以在 ExtJS 4 网格中使用
【发布时间】:2012-02-27 02:55:54
【问题描述】:

我刚刚开始使用 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']
        ));
    }
}
?>
  • 这种行为在 Symfony2 中是什么样的?
  • 控制器是否适合这种行为?
  • 解决此类问题的最佳实践是什么(在 Symfony 中)?

【问题讨论】:

    标签: php json model-view-controller symfony extjs4


    【解决方案1】:

    除了构建自己的响应之外,您还可以使用内置的 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);
        }
    }
    

    有关详细信息,请参阅 apidoc(2.6 版)。

    【讨论】:

      【解决方案2】:

      要使用return new JsonResponse(array('a' =&gt; 'value', 'b' =&gt; 'another-value');,您需要使用正确的命名空间:

      use Symfony\Component\HttpFoundation\JsonResponse;
      

      如此处所述:http://symfony.com/doc/current/components/http_foundation/introduction.html#creating-a-json-response

      【讨论】:

        【解决方案3】:

        使用

            return JsonResponse($data, StatusCode, Headers);
        

        【讨论】:

          【解决方案4】:

          简单。使用 FOSRestBundle 并且只从控制器返回 People 对象。

          【讨论】:

            【解决方案5】:

            我会避免使用模板来呈现数据,因为转义数据等的责任在模板中。相反,我按照您的建议在 PHP 中使用内置的 json_encode 函数。

            按照上一个答案中的建议在 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;
                }
            }
            ?>
            

            【讨论】:

            • 只是一个小注解,如果路由正确指定了_format 选项,Content-Type 标头由 Symfony2 自动设置,正如在 Responsehere 中看到的那样。由于在此示例中格式为 json,因此带有值 'application/json'Content-Type 标头将附加到响应中。
            【解决方案6】:

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

            是的。

            这种行为在 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,当然,创建相应的模板。

            【讨论】:

            • 其实我做到了。查看最后一个代码块{{ data | json_encode | raw }}
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-04-29
            • 2022-11-27
            • 1970-01-01
            • 2011-09-18
            • 1970-01-01
            • 2011-09-01
            相关资源
            最近更新 更多