我在我的控制器中使用搜索代码和分页代码,不用说重复代码就是编码习惯不好。那就是说Symfony2中最好的做法是什么,以避免在我的所有控制器中重复代码?
如果重新考虑了代码,我该如何访问?
控制器
// Search code
$results = null;
$query = $request->query->get('q');
if (!empty($query)) {
$em = $this->getDoctrine()->getManager();
$results = $em->createQueryBuilder()
->from('AcmeDemoBundle:Blog', 'b')
->select('b')
->where('b.title LIKE :search')
->setParameter(':search', "%${query}%")
->getQuery()
->getResult();
}
// Pagination code
$page = $request->get('page');
$count_per_page = 5;
$total_count = $this->getTotalBlogs();
$total_pages = ceil($total_count/$count_per_page);
if (!is_numeric($page)) {
$page = 1;
} else {
$page = floor($page);
}
if ($total_count <= $count_per_page) {
$page = 1;
}
if (($page * $count_per_page) > $total_count) {
$page = $total_pages;
}
$offset = 0;
if ($page > 1) {
$offset = $count_per_page * ($page - 1);
}
$em = $this->getDoctrine()->getManager();
$blogQuery = $em->createQueryBuilder()
->select('b')
->from('AcmeDemoBundle:Blog', 'b')
->addOrderBy('b.created', 'DESC')
->setFirstResult($offset)
->setMaxResults($count_per_page);
$blogFinalQuery = $blogQuery->getQuery();
$blogPage = $blogFinalQuery->getArrayResult();
foreach ($blogPage as $blog) {
$blog_id = $blog['id'];
$commentRepository = $this->getDoctrine()
->getRepository('AcmeDemoBundle:Comment');
$comments[] = $commentRepository->findByBlog($blog_id);
}
// exit(\ Doctrine \ Common \ Util \ Debug :: dump($ comments));
return $this->render('AcmeDemoBundlBundle:Default:index.html.twig', array(
'blogPage' => $blogPage,
'total_pages' => $total_pages,
'current_page' => $page,
'comments' => $comments,
'query' => $query,
'results' => $results,
));
答案 0 :(得分:1)
首先,您可以将所有自定义查询都放在custom repository classes中。我怀疑这将覆盖你在这种情况下所需的所有重复使用。
例如,在AcmeDemoBundle:Repository中创建一个BlogRepository类,并按如下方式注释Blog实体类以定义它的存储库类:
/**
* @ORM\Entity(repositoryClass="Acme\DemoBundle\Repository\BlogRepository")
*/
然后在存储库中为每个需要的自定义查询添加方法,同时牢记通常命名存储库方法的方式。看起来控制器方法getTotalBlogs()也可能是BogRepository上的一个方法,例如:
public function findFiltered($page, $count_per_page = 5, $filterText = '')
{
$total_count = $this->findTotal();
// Code to initialise page and offset here
$queryBuilder = $this->createQueryBuilder('blog');
$queryBuilder->...
...
}
请注意,如果没有传入$ filterText,则可以使用上述方法获取所有博客。您只需要这样的内容:
if (!empty($filterText))
{
queryBuilder->where('b.title LIKE :search')
->setParameter(':search', "%${query}%")
}
然后,可以使用方法创建CommentRepository,以查找给定博客(id)集的所有注释。请注意,您可以使用sql'IN'子句使用单个查询获取所有注释:
$commentQuery = $em->createQueryBuilder()
->select('comment')
->from('AcmeDemoBundle:Comment', 'comment')
->where('comment.blog IN (:ids)')
->setParameter('ids', $blogIds);
除了自定义存储库类,我还使用管理器服务(例如BlogManager)来封装业务流程。我的控制器主要使用管理器而不是直接使用存储库,但这取决于功能。
我有点困惑,你有一个整体结果查询只返回博客,其中标题就像搜索文本,而分页查询返回(一页)所有博客。那可能只是因为您的代码正在进行中?