PHPackages                             zenstruck/porpaginas - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. zenstruck/porpaginas

Abandoned → [zenstruck/collection](/?search=zenstruck%2Fcollection)ArchivedLibrary

zenstruck/porpaginas
====================

Library that generically solves several pagination issues with DAO/repository abstractions.

v2.0.0(8y ago)1565MITPHPPHP ^7.1

Since Dec 6Pushed 5y ago1 watchersCompare

[ Source](https://github.com/kbond/porpaginas)[ Packagist](https://packagist.org/packages/zenstruck/porpaginas)[ RSS](/packages/zenstruck-porpaginas/feed)WikiDiscussions master Synced 2mo ago

READMEChangelog (4)Dependencies (6)Versions (8)Used By (0)

zenstruck/porpaginas
====================

[](#zenstruckporpaginas)

[![Build Status](https://camo.githubusercontent.com/9c278122d732ba4ba89e95baaa0c981620a81839dce6db8e61c85e96740d198d/687474703a2f2f696d672e736869656c64732e696f2f7472617669732f6b626f6e642f706f72706167696e61732e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/kbond/porpaginas)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/9476b27d3bde2e6c9cb693f64e3fd63bb86fc7069174c62ac634cb574a3918a4/687474703a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f6b626f6e642f706f72706167696e61732e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/kbond/porpaginas/)[![Code Coverage](https://camo.githubusercontent.com/843e380267221e628bb9f8d2fef00c391572c40bbfd93b6a54a0ffb1a27fc65e/687474703a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f636f7665726167652f672f6b626f6e642f706f72706167696e61732e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/kbond/porpaginas/)[![StyleCI](https://camo.githubusercontent.com/9d178bfabfe85ef4ad5c0dc28d0324c54a539a8eb84a2249c4cda54908b4f2b7/68747470733a2f2f7374796c6563692e696f2f7265706f732f34323635363938382f736869656c64)](https://styleci.io/repos/42656988)[![Latest Stable Version](https://camo.githubusercontent.com/b7091c7cd3b306fb572e29e5bfbff94a4615b7a865b4fe7d586a45e853d654cf/687474703a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7a656e73747275636b2f706f72706167696e61732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/zenstruck/porpaginas)[![License](https://camo.githubusercontent.com/033328a6c00a247f47f748c8d6a4b977fcc32e9a9563a5e7dca6ff551ea93fb2/687474703a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f7a656e73747275636b2f706f72706167696e61732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/zenstruck/porpaginas)

**NOTE**: This library is a fork of [beberlei/porpaginas](https://github.com/beberlei/porpaginas).

This library solves a bunch of issues that comes up with APIs of Repository classes alot:

- You need different methods for paginatable and non-paginatable finder methods.
- You need to expose the underlying data-source and return query objects from your repository.
- Serialization of paginators should be easily possible for REST APIs

Both Pagerfanta and KnpLabs Pager don't solve this issue and their APIs are really problematic in this regard. You need to return the query objects or adapters for paginators from your repositories to get it working and then use an API on the controller side to turn them into a paginated result set.

Porpaginas solves this by introducing a sane abstraction for paginated results. For rendering purposes you can integrate with either Pagerfanta or KnpLabs Pager, this library is not about reimplementating the view part of pagination.

Central part of this library is the interface `Result`:

```
namespace Zenstruck\Porpaginas;

interface Result extends \Countable, \IteratorAggregate, \JsonSerializable
{
    public function take(int $offset, int $limit): Page;

    /**
     * Return the number of all results in the paginatable.
     */
    public function count(): int;

    /**
     * Return an iterator over all results of the paginatable.
     */
    public function getIterator(): \Iterator;
}
```

This API offers you two ways to iterate over the paginatable result, either the full result or a paginated window of the result using `take()`. One drawback is that the query is always lazily executed inside the `Result` and not directly in the repository.

The `Page` interface returned from `Result::take()` looks like this:

```
namespace Zenstruck\Porpaginas;

interface Page extends \Countable, \IteratorAggregate, \JsonSerializable
{
    /**
     * Return the number of results on the currrent page.
     */
    public function count(): int;

    /**
     * Return the number of ALL results in the paginatable..
     */
    public function totalCount(): int;

    /**
     * Return an iterator over selected windows of results of the paginatable.
     */
    public function getIterator(): \Iterator;
}
```

Supported Backends
------------------

[](#supported-backends)

- Array
- Doctrine ORM
- Doctrine DBAL

Example
-------

[](#example)

Take the following example using Doctrine ORM:

```
use Zenstruck\Porpaginas\Result;

class UserRepository extends EntityRepository
{
    public function findAllUsers(): Result
    {
        $qb = $this->createQueryBuilder('u')->orderBy('u.username');

        return new ORMQueryResult($qb);
    }
}

class UserController
{
    /**
     * @var UserRepository
     */
    private $userRepository;

    public function listAction(Request $request)
    {
        $result = $this->userRepository->findAllUsers();
        // no filtering by page, iterate full result

        return array('users' => $result);
    }

    public function porpaginasListAction(Request $request)
    {
        $result = $this->userRepository->findAllUsers();

        $paginator = $result->take(($request->get('page', 1)-1) * 20, 20);

        return array('users' => $paginator);
    }
}
```

This library also comes with a pagination helper. Using the `Pager`, the above controller's `porpaginasListAction()` could be re-written as follows:

```
use Zenstruck\Porpaginas\Pager;

class UserController
{
    /**
     * @var UserRepository
     */
    private $userRepository;

    public function porpaginasListAction(Request $request)
    {
        $result = $this->userRepository->findAllUsers();

        return array('users' => $result->paginate($request->get('page', 1)));
    }
}
```

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity15

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity63

Established project with proven stability

 Bus Factor1

Top contributor holds 75.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~137 days

Recently: every ~159 days

Total

6

Last Release

3016d ago

Major Versions

v1.1.0 → 2.x-dev2018-02-08

### Community

Maintainers

![](https://www.gravatar.com/avatar/707369cc916e0ea1aacbf077dcba464f611cef879f024d8944311a54a15224b3?d=identicon)[kbond](/maintainers/kbond)

---

Top Contributors

[![kbond](https://avatars.githubusercontent.com/u/127811?v=4)](https://github.com/kbond "kbond (114 commits)")[![beberlei](https://avatars.githubusercontent.com/u/26936?v=4)](https://github.com/beberlei "beberlei (27 commits)")[![stof](https://avatars.githubusercontent.com/u/439401?v=4)](https://github.com/stof "stof (7 commits)")[![fightmaster](https://avatars.githubusercontent.com/u/648770?v=4)](https://github.com/fightmaster "fightmaster (2 commits)")[![aitboudad](https://avatars.githubusercontent.com/u/1753742?v=4)](https://github.com/aitboudad "aitboudad (1 commits)")

---

Tags

pagepaginatorpaginationpaging

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/zenstruck-porpaginas/health.svg)

```
[![Health](https://phpackages.com/badges/zenstruck-porpaginas/health.svg)](https://phpackages.com/packages/zenstruck-porpaginas)
```

###  Alternatives

[pagerfanta/pagerfanta

Pagination for PHP

42550.0M245](/packages/pagerfanta-pagerfanta)[beberlei/porpaginas

Library that generically solves several pagination issues with DAO/repository abstractions.

163612.6k11](/packages/beberlei-porpaginas)[stefangabos/zebra_pagination

A generic, Twitter Bootstrap compatible, PHP pagination library that automatically generates navigation links

11122.9k](/packages/stefangabos-zebra-pagination)[usmanhalalit/strana

Pagination library for PHP, framework agnostic, with built-in adapters for Doctrine, Eloquent, Pixie and PHP Array.

947.4k3](/packages/usmanhalalit-strana)[paysera/lib-pagination

Paginates Doctrine QueryBuilder using cursor based or offset based pagination

13191.8k1](/packages/paysera-lib-pagination)[2createstudio/carbon-pagination

A handy WordPress library for building all kinds of paginations.

152.4k](/packages/2createstudio-carbon-pagination)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
