Pagination
| Slice in repository | |
| Page math | |
| Link rendering in Twig | |
| Total counts |
Slice in repository
Never fetch ten thousand rows to show ten. Ask the repository for one slice with an offset and a limit.
The method below builds the slice with the query builder. First result skips rows, max results caps the page.
class PostRepository { public function page(int $offset, int $limit): array { return $this->createQueryBuilder("p") ->setFirstResult($offset) ->setMaxResults($limit) ->getQuery() ->getResult(); } }
Page math
Page numbers start at one while offsets start at zero. Clamp bad input so page zero or minus five still shows page one.
Total pages come from the ceiling of total over limit. Ten rows with a limit of three need four pages.
$page = max(1, $current); $limit = 10; $offset = ($page - 1) * $limit; $totalPages = (int) ceil($total / $limit);
Link rendering in Twig
Pages need prev and next links plus a short row of numbers. Build the numbers in PHP and print them with a loop in the template.
The sketch below prepares the range and the two neighbors. The template only loops and prints.
$pages = range(1, $totalPages); $prev = max(1, $page - 1); $next = min($totalPages, $page + 1);
Total counts
A pager also needs the total row count. Run a count query once and reuse the number for math and links.
Count queries stay cheap because the base returns one number. Cache the total when the table rarely changes.
$countQuery = $repo->createQueryBuilder("p") ->select("COUNT(p.id)") ->getQuery(); $total = (int) $countQuery->getSingleScalarResult();
Next: File uploads
Article author: Arthur Isaev