PHPackages                             wiistriker/doctrine-cursor-iterator - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. wiistriker/doctrine-cursor-iterator

Abandoned → [wiistriker/doctrine-cursor-paginator](/?search=wiistriker%2Fdoctrine-cursor-paginator)Library[Utility &amp; Helpers](/categories/utility)

wiistriker/doctrine-cursor-iterator
===================================

Iterate through large datasets

20PHP

Since Jan 22Pushed 3mo agoCompare

[ Source](https://github.com/wiistriker/doctrine-cursor-paginator)[ Packagist](https://packagist.org/packages/wiistriker/doctrine-cursor-iterator)[ RSS](/packages/wiistriker-doctrine-cursor-iterator/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

Doctrine ORM and DBAL Cursor Paginator for large datasets
=========================================================

[](#doctrine-orm-and-dbal-cursor-paginator-for-large-datasets)

Iterate through large database results with easy

Usage for ORM
-------------

[](#usage-for-orm)

Create query builder as usual. Dont forget about `orderBy` and `maxResults`.

```
$testEntityRepository = $this->entityManager->getRepository(TestEntity::class);
$qb = $testEntityRepository->createQueryBuilder('t')
    ->orderBy('t.id', 'ASC')
    ->setMaxResults(100)
;

/** @var DoctrineORMCursorPaginator $cursorPaginator */
$cursorPaginator = new DoctrineORMCursorPaginator($qb);

foreach ($cursorPaginator as $testEntity) {
    //...
}
```

DoctrineORMCursorPaginator will hold only 100 records in memory to prevent memory leaks and efficiently iterate through even large datasets.

First sql:

`SELECT ... FROM table ORDER BY id ASC LIMIT 100`

Next:

`SELECT ... FROM table WHERE id > {$id_from_last_record} ORDER BY id ASC LIMIT 100`

You can also specify more order by fields

```
$testEntityRepository = $this->entityManager->getRepository(TestEntity::class);
$qb = $testEntityRepository->createQueryBuilder('t')
    ->select('t.id', 't.createdAt')
    ->orderBy('t.createdAt', 'DESC')
    ->addOrderBy('t.id', 'DESC')
    ->setMaxResults(100)
;

/** @var DoctrineORMCursorPaginator $cursorPaginator */
$cursorPaginator = new DoctrineORMCursorPaginator($qb);

foreach ($cursorPaginator as $testEntity) {
    //...
}
```

You can change hydration mode

```
$cursorPaginator = new DoctrineORMCursorPaginator($qb, AbstractQuery::HYDRATE_ARRAY);
```

And even set query hints

```
$cursorPaginator = new DoctrineORMCursorPaginator(
    queryBuilder: $qb,
    queryHints: [
        'fetchMode' => [
            TestEntity::class => [
                'field' => ClassMetadataInfo::FETCH_EAGER
            ]
        ]
    ]
);
```

You wanna batch? Lets batch:

```
$cursorPaginator = new DoctrineORMCursorPaginator($qb);

foreach ($cursorPaginator->batch() as $entities) {
    foreach ($entities as $testEntity) {
        $cnt++;
    }
}
```

By default batch size equals to `maxResults` but you can also specify desired amount by yourself:

```
$my_batch_size = 1000;

$cursorPaginator = new DoctrineORMCursorPaginator($qb);

foreach ($cursorPaginator->batch($my_batch_size) as $entities) {
}
```

Usage for DBAL
--------------

[](#usage-for-dbal)

Just use `DoctrineDBALCursorPaginator` instead.

```
$queryBuilder = $this->connection->createQueryBuilder();

$queryBuilder
    ->select('id', 'name')
    ->from('test')
    ->orderBy('id', 'ASC')
    ->setMaxResults(100)
;

$cursorPaginator = new DoctrineDBALCursorPaginator($queryBuilder);

foreach ($cursorPaginator as $row) {
}
```

###  Health Score

19

—

LowBetter than 10% of packages

Maintenance56

Moderate activity, may be stable

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% 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.

### Community

Maintainers

![](https://www.gravatar.com/avatar/2c85524bc58444ab554ec47663bd1716ef1db841d7e245a4569f67c7da8e2d0c?d=identicon)[wiistriker](/maintainers/wiistriker)

---

Top Contributors

[![wiistriker](https://avatars.githubusercontent.com/u/967817?v=4)](https://github.com/wiistriker "wiistriker (12 commits)")

### Embed Badge

![Health badge](/badges/wiistriker-doctrine-cursor-iterator/health.svg)

```
[![Health](https://phpackages.com/badges/wiistriker-doctrine-cursor-iterator/health.svg)](https://phpackages.com/packages/wiistriker-doctrine-cursor-iterator)
```

PHPackages © 2026

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