Symfony2将任何HTML控制器输出为JSON

use*_*356 7 symfony

我有一个在Symfony2中创建的网站,现在我想要在移动应用程序中提供该网站的许多功能.
我的想法是通过附加一个简单的URL变量,然后它将在JSON中输出相关页面请求的所有变量.

所以,如果我连接到

www.domain.com/profile/john-smith
Run Code Online (Sandbox Code Playgroud)

它现在返回HTML页面.
但是,如果我去

www.domain.com/profile/john-smith?app
Run Code Online (Sandbox Code Playgroud)

然后它返回一个名称,年龄和其他配置文件信息的JSON对象.
我的应用程序代码然后接收JSON和进程.

我看不到任何安全问题,因为它实际上是JSON中提供的变量而没有HTML.

通过执行上述操作,我可以创建所有应用程序代码,只需调用与网页相同的URL,这将返回JSON中的变量,并节省了对更多服务器端工作的需求.

问题是:如果不修改每个控制器,我该怎么做?

我无法想象一个事件监听器会这样做吗?也许我可以拦截Response对象并删除所有HTML?

有关最佳实践方法的任何想法吗?它应该很容易编码,但我正试图弄清楚它的设计.

jam*_*s_t 5

有一种正确的方法来配置此任务的路由

  article_show:
  path:     /articles/{culture}/{year}/{title}.{_format}
  defaults: { _controller: AcmeDemoBundle:Article:show, _format: html }
  requirements:
      culture:  en|fr
      _format:  html|rss
      year:     \d+
Run Code Online (Sandbox Code Playgroud)

但是,这仍然需要您使用其他控制结构编辑每个Controller来处理该输出.

要解决这个问题,你可以做两件事.

  1. 为您拥有的每个模板创建json模板,然后将html替换template.html.twigtemplate.'.$format.'.twig.(注意确保用户无法在URL中验证参数,这将是一个主要的安全风险).

  2. 创建自己的抽象控制器类并覆盖render方法以检查请求的格式并根据该格式提供输出.

    class MyAbstractController extends Symfony\Bundle\FrameworkBundle\Controller\Controller
    {
        public function render($view, array $parameters = array(), Response $response = null)
        {
            if($this->getRequest()->getRequestFormat() == 'json')
            {
                return new Response(json_encode($parameters));
            }
            else
            {
               parent::render($view, $parameters, $response);
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

注意上面的代码是一个原型,不要指望它开箱即用.

我个人认为第二种方法更正确,因为没有重复的代码,安全问题也更少.