我刚刚开始使用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']
));
}
}
?>
答案 0 :(得分:12)
控制器是否适合这种行为?
是
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
)));
}
// ...
}
Controller以路由配置中设置的格式呈现数据。在我们的例子中,它是json格式。
以下是可能模板的示例:
{# app/Resourses/views/base.json.twig #}
{{ data | json_encode | raw }}
这种方法的优点(我的意思是使用_format)就是如果你决定从json切换到例如xml而不是没有问题 - 只需在路由配置中替换_format,当然,创建相应的模板。 / p>
答案 1 :(得分:8)
我会避免使用模板来呈现数据,因为然后在模板中负责转义数据等。相反,我在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;
}
}
?>
答案 2 :(得分:1)
要使用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
答案 3 :(得分: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);
}
}
答案 4 :(得分:0)
简单。使用FOSRestBundle并仅从控制器返回People对象。
答案 5 :(得分:-2)
使用
return JsonResponse($data, StatusCode, Headers);