在 Symfony 中使用分页 class 的正确方法
The right way of using a pagination class in Symfony
我正在尝试使用这个 Symfony 包:
https://github.com/KnpLabs/KnpPaginatorBundle
在文档中,他们将其用作控制器。因此他们可以轻松访问服务容器或请求对象。
但据我了解,Doctrine 查询应该在存储库中,而不是控制器中,对吗?而且我已经有了 returning 记录功能。只是分页服务在实例化时不期望 "results" 。它想要查询。所以我不能 return "results" 到控制器,而是在这个函数的中间使用分页器。
另一方面,像玩服务或请求这样的东西确实属于控制器。
那么应该怎么做呢?起初我想到了将 "knp_paginator" 服务和请求对象注入到存储库中。但我认为这不是正确的方法。
假设您有一个 Custom Repository Class, 您可以在该存储库中有一个方法,该方法 returns 一个查询或一个有效的查询生成器实例,然后您从控制器调用该方法并传递它到 paginate()
方法。
我会说 Request 对象不应该比 Controller 更深入堆栈。
没有什么能阻止您将分页器直接注入您的自定义存储库,那么为什么不这样做呢?
your.repository.service.definition:
class: Your\Repository\Class
# for symfony 2.3
factory_service: doctrine
factory_method: getRepository
# for symfony 2.8 and higher
factory: ["@doctrine.orm.entity_manager", getRepository]
arguments:
- YourBundle:YourEntity
calls:
- [setPaginator, ["@knp_paginator"]]
在存储库中,您应该可以使用 QueryBuilder 的分页器:
public function setPaginator($paginator)
{
$this->paginator = $paginator;
}
...
$this->paginator->paginate($qb->getQuery(), $page, $limit);
为了将您的 $page
和 $limit
变量放入存储库,您不需要 Request 对象。只需将它们作为参数传递给存储库调用:
// In your controller
// You can use forms here if you want, but for brevity:
$criteria = $request->get('criteria');
$page = $request->get('page');
$limit = $request->get('limit');
$paginatedResults = $myCustomRepository->fetchPaginatedData($criteria, $page, $limit);
将请求对象进一步向下传递到控制器意味着您的抽象存在漏洞。了解 Request 对象与您的应用程序无关。实际上,请求很可能来自其他来源,例如 CLI 命令。由于错误的抽象级别,您不希望从那里创建请求对象。
例如,$qb 由自定义存储库 return 编辑(不是 return 结果,而只是它的查询生成器)
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$qb->getQuery(),
$request->query->getInt($pageParameterName, 1),
$perPage,
array('pageParameterName' => $pageParameterName)
);
我正在尝试使用这个 Symfony 包: https://github.com/KnpLabs/KnpPaginatorBundle
在文档中,他们将其用作控制器。因此他们可以轻松访问服务容器或请求对象。
但据我了解,Doctrine 查询应该在存储库中,而不是控制器中,对吗?而且我已经有了 returning 记录功能。只是分页服务在实例化时不期望 "results" 。它想要查询。所以我不能 return "results" 到控制器,而是在这个函数的中间使用分页器。
另一方面,像玩服务或请求这样的东西确实属于控制器。
那么应该怎么做呢?起初我想到了将 "knp_paginator" 服务和请求对象注入到存储库中。但我认为这不是正确的方法。
假设您有一个 Custom Repository Class, 您可以在该存储库中有一个方法,该方法 returns 一个查询或一个有效的查询生成器实例,然后您从控制器调用该方法并传递它到 paginate()
方法。
我会说 Request 对象不应该比 Controller 更深入堆栈。
没有什么能阻止您将分页器直接注入您的自定义存储库,那么为什么不这样做呢?
your.repository.service.definition:
class: Your\Repository\Class
# for symfony 2.3
factory_service: doctrine
factory_method: getRepository
# for symfony 2.8 and higher
factory: ["@doctrine.orm.entity_manager", getRepository]
arguments:
- YourBundle:YourEntity
calls:
- [setPaginator, ["@knp_paginator"]]
在存储库中,您应该可以使用 QueryBuilder 的分页器:
public function setPaginator($paginator)
{
$this->paginator = $paginator;
}
...
$this->paginator->paginate($qb->getQuery(), $page, $limit);
为了将您的 $page
和 $limit
变量放入存储库,您不需要 Request 对象。只需将它们作为参数传递给存储库调用:
// In your controller
// You can use forms here if you want, but for brevity:
$criteria = $request->get('criteria');
$page = $request->get('page');
$limit = $request->get('limit');
$paginatedResults = $myCustomRepository->fetchPaginatedData($criteria, $page, $limit);
将请求对象进一步向下传递到控制器意味着您的抽象存在漏洞。了解 Request 对象与您的应用程序无关。实际上,请求很可能来自其他来源,例如 CLI 命令。由于错误的抽象级别,您不希望从那里创建请求对象。
例如,$qb 由自定义存储库 return 编辑(不是 return 结果,而只是它的查询生成器)
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$qb->getQuery(),
$request->query->getInt($pageParameterName, 1),
$perPage,
array('pageParameterName' => $pageParameterName)
);