Класс Paginator
Класс Paginator принимает объект Query или QueryBuilder и разбивает результат выборки на страницы. Он реализует интерфейсы IteratorAggregate и Countable, поэтому его можно перебирать в цикле и получать общее количество элементов. Первым параметром передаётся запрос, который нужно разбить на страницы.
Синтаксис
use Doctrine\ORM\Tools\Pagination\Paginator;
$paginator = new Paginator($query, $fetchJoinCollection);
Первый параметр $query - это объект Query или QueryBuilder. Второй параметр $fetchJoinCollection указывает, содержит ли запрос fetch join коллекцию, и по умолчанию равен true.
Пример
Давайте разобьём список статей на страницы в контроллере:
<?php
namespace App\Controller;
use App\Entity\Article;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class ArticleController extends AbstractController
{
#[Route('/articles/{page}', name: 'article_index')]
public function index(EntityManagerInterface $em, int $page = 1): Response
{
$query = $em->createQueryBuilder()
->select('a')
->from(Article::class, 'a')
->setFirstResult(($page - 1) * 10)
->setMaxResults(10)
->getQuery();
$paginator = new Paginator($query, false);
$res = count($paginator);
return new Response((string) $res);
}
}
?>
Результат выполнения кода для адреса /articles/1 при наличии 25 статей:
25
Пример
Давайте переберём элементы страницы в цикле:
<?php
namespace App\Controller;
use App\Entity\Article;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class ArticleController extends AbstractController
{
#[Route('/articles/{page}', name: 'article_index')]
public function index(EntityManagerInterface $em, int $page = 1): Response
{
$query = $em->createQueryBuilder()
->select('a')
->from(Article::class, 'a')
->setFirstResult(($page - 1) * 10)
->setMaxResults(10)
->getQuery();
$paginator = new Paginator($query, false);
$res = [];
foreach ($paginator as $article) {
$res[] = $article->getTitle();
}
return new Response(implode(', ', $res));
}
}
?>
Результат выполнения кода:
"article 1, article 2, article 3"
Пример
Давайте передадим объект Paginator в Twig-шаблон:
<?php
namespace App\Controller;
use App\Entity\Article;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class ArticleController extends AbstractController
{
#[Route('/articles/{page}', name: 'article_index')]
public function index(EntityManagerInterface $em, int $page = 1): Response
{
$query = $em->createQueryBuilder()
->select('a')
->from(Article::class, 'a')
->setFirstResult(($page - 1) * 10)
->setMaxResults(10)
->getQuery();
$paginator = new Paginator($query, false);
return $this->render('article/index.html.twig', [
'paginator' => $paginator,
]);
}
}
?>
Теперь выведем статьи и общее количество в шаблоне:
{% for article in paginator %}
<p>{{ article.title }}</p>
{% endfor %}
<p>Total: {{ paginator|length }}</p>
Результат выполнения кода:
<p>article 1</p>
<p>article 2</p>
<p>article 3</p>
<p>Total: 25</p>
Смотрите также
-
метод
getIterator,
который возвращает итератор по элементам страницы -
метод
count,
который возвращает общее количество элементов -
метод
getQuery,
который возвращает исходный запрос -
метод
setUseOutputWalkers,
который управляет обходом результатов при выборке