PHPackages                             maxgoryunov/saving-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. maxgoryunov/saving-iterator

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

maxgoryunov/saving-iterator
===========================

True Caching Iterator for PHP

1.0(8mo ago)53[2 issues](https://github.com/MaxGoryunov/saving-iterator/issues)[3 PRs](https://github.com/MaxGoryunov/saving-iterator/pulls)PHPPHP &gt;=8.1CI passing

Since Jul 11Pushed 8mo ago3 watchersCompare

[ Source](https://github.com/MaxGoryunov/saving-iterator)[ Packagist](https://packagist.org/packages/maxgoryunov/saving-iterator)[ RSS](/packages/maxgoryunov-saving-iterator/feed)WikiDiscussions master Synced 5d ago

READMEChangelog (6)Dependencies (7)Versions (18)Used By (0)

[![EO principles respected here](https://camo.githubusercontent.com/5c7a27b75a8da4be52680df944abec4ccc4d0151df036e0793b8c9b16cbe3d1e/68747470733a2f2f7777772e656c6567616e746f626a656374732e6f72672f62616467652e737667)](https://www.elegantobjects.org)[![DevOps By Rultor.com](https://camo.githubusercontent.com/fdefe34f2c83fbb73f00b469670affb1de8d1de987f20178dbdc10ac5a665fc7/687474703a2f2f7777772e72756c746f722e636f6d2f622f4d6178476f7279756e6f762f736176696e672d6974657261746f72)](http://www.rultor.com/p/MaxGoryunov/saving-iterator)

[![PHP-Composer-Build](https://github.com/MaxGoryunov/saving-iterator/actions/workflows/php.yml/badge.svg)](https://github.com/MaxGoryunov/saving-iterator/actions/workflows/php.yml/badge.svg)[![Build Status](https://camo.githubusercontent.com/531d11b0304cc847d61b527e39cc25e9d115e69292387924574984cc593c7dbe/68747470733a2f2f6170702e7472617669732d63692e636f6d2f4d6178476f7279756e6f762f736176696e672d6974657261746f722e7376673f6272616e63683d6d6173746572)](https://app.travis-ci.com/MaxGoryunov/saving-iterator)[![Build Status](https://camo.githubusercontent.com/ea83559925b6f191813dd3b9668a9a56e5c7eea77603b561b0b7c540a71c6c2e/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f4d6178476f7279756e6f762f736176696e672d6974657261746f722f6261646765732f6275696c642e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/MaxGoryunov/saving-iterator/build-status/master)[![Build status](https://camo.githubusercontent.com/aa6495efcb2f0fc7718127dc075b59bc92d9c59d8934d88caefb0ca2e60d76ec/68747470733a2f2f63692e6170707665796f722e636f6d2f6170692f70726f6a656374732f7374617475732f6e34673832383875377531786b6a30352f6272616e63682f6d61737465723f7376673d74727565)](https://ci.appveyor.com/project/MaxGoryunov/saving-iterator/branch/master)[![MaxGoryunov](https://camo.githubusercontent.com/666edadb84a0a1a80613114719707596388a85265954f685546831f2aab2d15c/68747470733a2f2f636972636c6563692e636f6d2f67682f4d6178476f7279756e6f762f736176696e672d6974657261746f722e7376673f7374796c653d737667)](https://app.circleci.com/pipelines/github/MaxGoryunov/saving-iterator)

[![PDD status](https://camo.githubusercontent.com/d614a4a4f617dc79c7fcb9487db81e79536e8a175700744a2599fe53f11089e1/68747470733a2f2f7777772e307064642e636f6d2f7376673f6e616d653d4d6178476f7279756e6f762f736176696e672d6974657261746f72)](https://www.0pdd.com/p?name=MaxGoryunov/saving-iterator)[![codecov](https://camo.githubusercontent.com/b73daa90d5ea9c12ff41169ce460ff32ae35aed6d3b987e4963699c32384783f/68747470733a2f2f636f6465636f762e696f2f67682f4d6178476f7279756e6f762f736176696e672d6974657261746f722f6272616e63682f6d61737465722f67726170682f62616467652e7376673f746f6b656e3d4b59525a30554b384538)](https://codecov.io/gh/MaxGoryunov/saving-iterator)[![Mutation testing badge](https://camo.githubusercontent.com/6d0d619242cd710ea8dc22cc724f21e0c63a3aa7e738d031b843eac26b96a24f/68747470733a2f2f696d672e736869656c64732e696f2f656e64706f696e743f7374796c653d666c61742675726c3d687474707325334125324625324662616467652d6170692e737472796b65722d6d757461746f722e696f2532466769746875622e636f6d2532464d6178476f7279756e6f76253246736176696e672d6974657261746f722532466d6173746572)](https://infection.github.io)[![Latest Stable Version](https://camo.githubusercontent.com/936ea99a0a4a99f66287a3d2771cb82c26b9814ccd5be1f74b731d62981cfb8e/687474703a2f2f706f7365722e707567782e6f72672f6d6178676f7279756e6f762f736176696e672d6974657261746f722f76)](https://packagist.org/packages/maxgoryunov/saving-iterator)[![License: MIT](https://camo.githubusercontent.com/08cef40a9105b6526ca22088bc514fbfdbc9aac1ddbf8d4e6c750e3a88a44dca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e737667)](https://github.com/MaxGoryunov/saving-iterator/blob/master/LICENSE)

[![Maintainability](https://camo.githubusercontent.com/ed01856cc2ca820c0eaf4cf90b0de568ed6faf36fba8188ba4f65eeb65f61b0a/68747470733a2f2f6170692e636f6465636c696d6174652e636f6d2f76312f6261646765732f64373231613566636134393031303130353230652f6d61696e7461696e6162696c697479)](https://codeclimate.com/github/MaxGoryunov/saving-iterator/maintainability)[![Codacy Badge](https://camo.githubusercontent.com/c51f2670ccdeedb72c333f6c6dcb3aa182a448120c0e451456db3acf7705adb4/68747470733a2f2f6170702e636f646163792e636f6d2f70726f6a6563742f62616467652f47726164652f3939336539313438306466613432333961373830643564376166353238643330)](https://www.codacy.com/gh/MaxGoryunov/saving-iterator/dashboard?utm_source=github.com&utm_medium=referral&utm_content=MaxGoryunov/saving-iterator&utm_campaign=Badge_Grade)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/3608019718a8fcd5b7836cf1287fd04aa4183fac4a7ae7e1be5adcd9174bd1e3/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f4d6178476f7279756e6f762f736176696e672d6974657261746f722f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/MaxGoryunov/saving-iterator/?branch=master)[![CodeFactor](https://camo.githubusercontent.com/cd149d34f0076b51024738efe79e9e3c1900b80ba6ee460d9e9a78b2f3da5de4/68747470733a2f2f7777772e636f6465666163746f722e696f2f7265706f7369746f72792f6769746875622f6d6178676f7279756e6f762f736176696e672d6974657261746f722f6261646765)](https://www.codefactor.io/repository/github/maxgoryunov/saving-iterator)

[![Quality Gate Status](https://camo.githubusercontent.com/f9b9192467ed6d29412c5de7ba854eed86f6f6b921ef7bc25d03f04d09996f03/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d4d6178476f7279756e6f765f736176696e672d6974657261746f72266d65747269633d616c6572745f737461747573)](https://sonarcloud.io/summary/new_code?id=MaxGoryunov_saving-iterator)[![Bugs](https://camo.githubusercontent.com/908319b038c1f0c4024aed52b82131fbbceee5d46aad14e5802b29ef2f65f418/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d4d6178476f7279756e6f765f736176696e672d6974657261746f72266d65747269633d62756773)](https://sonarcloud.io/summary/new_code?id=MaxGoryunov_saving-iterator)[![Code Smells](https://camo.githubusercontent.com/7cdb23cd66a4e27fd88b1c313306ec5738e25cb81d739047d9e81a60bcc1f2e8/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d4d6178476f7279756e6f765f736176696e672d6974657261746f72266d65747269633d636f64655f736d656c6c73)](https://sonarcloud.io/summary/new_code?id=MaxGoryunov_saving-iterator)[![Reliability Rating](https://camo.githubusercontent.com/ef75a614410336e9ab7e281ad792f9ea882c07610a42814e41901202f186461f/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d4d6178476f7279756e6f765f736176696e672d6974657261746f72266d65747269633d72656c696162696c6974795f726174696e67)](https://sonarcloud.io/summary/new_code?id=MaxGoryunov_saving-iterator)

[![Duplicated Lines (%)](https://camo.githubusercontent.com/fbb94bea94930f4ea01ac4140b029574cb45f0dd16954dc57d53eb118af58d23/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d4d6178476f7279756e6f765f736176696e672d6974657261746f72266d65747269633d6475706c6963617465645f6c696e65735f64656e73697479)](https://sonarcloud.io/summary/new_code?id=MaxGoryunov_saving-iterator)[![Technical Debt](https://camo.githubusercontent.com/94c0f1795b0aa7076446a967ec3856e2d8455a432d98501269e19ddd4d5e43ef/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d4d6178476f7279756e6f765f736176696e672d6974657261746f72266d65747269633d7371616c655f696e646578)](https://sonarcloud.io/summary/new_code?id=MaxGoryunov_saving-iterator)[![Maintainability Rating](https://camo.githubusercontent.com/4725b07813a6fb517eb6cb0c81998dac704aa48a9e9ddc111b1bdb7199e3c183/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d4d6178476f7279756e6f765f736176696e672d6974657261746f72266d65747269633d7371616c655f726174696e67)](https://sonarcloud.io/summary/new_code?id=MaxGoryunov_saving-iterator)

[![Hits-of-Code](https://camo.githubusercontent.com/6a8d9a1a2beac4a6a176a9b9004da20eb72c7a4a7496c8860c02bb0652f15156/68747470733a2f2f686974736f66636f64652e636f6d2f6769746875622f4d6178476f7279756e6f762f736176696e672d6974657261746f723f6272616e63683d6d6173746572)](https://hitsofcode.com/github/MaxGoryunov/saving-iterator/view)[![Lines-of-Code](https://camo.githubusercontent.com/06ddbb570864bc2f8ba40b1c931813cfb7dedcfb6aac3c3936565a89ec7c902f/68747470733a2f2f746f6b65692e72732f62312f6769746875622f4d6178476f7279756e6f762f736176696e672d6974657261746f723f6272616e63683d6d6173746572)](https://camo.githubusercontent.com/06ddbb570864bc2f8ba40b1c931813cfb7dedcfb6aac3c3936565a89ec7c902f/68747470733a2f2f746f6b65692e72732f62312f6769746875622f4d6178476f7279756e6f762f736176696e672d6974657261746f723f6272616e63683d6d6173746572)[![PHP Version](https://camo.githubusercontent.com/62c8777ac6f843bf105fcf3ee35b14bc06caec6da06df95975bcbf2a36e0f7a0/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f4d6178476f7279756e6f762f736176696e672d6974657261746f72)](https://camo.githubusercontent.com/62c8777ac6f843bf105fcf3ee35b14bc06caec6da06df95975bcbf2a36e0f7a0/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f4d6178476f7279756e6f762f736176696e672d6974657261746f72)

**Saving Iterator** is a true caching iterator for PHP. It aims to solve the same problems as PHP's [Caching Iterator](https://www.php.net/manual/ru/class.cachingiterator.php) but with a [better encapsulation of data](https://www.yegor256.com/2016/11/21/naked-data.html) in mind. It has properties of both `Iterator` and `array`.

How to use
----------

[](#how-to-use)

Require it with [Composer](https://getcomposer.org/download/):

```
composer require maxgoryunov/saving-iterator
```

Then include this in your `index.php` or any other main file:

```
require __DIR__ . "./vendor/autoload.php";
```

If you have any questions, ask them at [Discussions](https://github.com/MaxGoryunov/saving-iterator/discussions).

Decorating Iterators
--------------------

[](#decorating-iterators)

In order to use `SavingIterator` you need to provide a source and a target. Any object with `Iterator` interface is a suitable source. Target needs to be an `AddingIterator`(usually `ArrayAddingIterator` is enough):

```
$squares = new SavingIterator(
    new SquaringIterator(
        [1, 2, 3, 4, 5, 6]
    ),
    new ArrayAddingIterator()
);
```

It is also possible to use `SavingIterator` without providing a target. In this case, it will use a default `AddingIterator` storage:

```
$squares = new SavingIterator(
    new SquaringIterator(
        [1, 2, 3, 4, 5, 6]
    )
);
```

If the origin object is not an `Iterator` then wrap it in `TransparentIterator`:

```
$wrapped = new SavingIterator(
    new TransparentIterator($origin),
    new ArrayAddingIterator()
);
```

If you do not want to store nulls in your `AddingIterator` then use `ValidAddingIterator`:

```
$valid = new ValidAddingIterator(
    new ArrayAddingIterator()
);
```

Decorating Generators
---------------------

[](#decorating-generators)

You can also use it with `Generators`. If the iterator is called twice, rewind exception will **not** be thrown. Just pass a function which returns a `Generator` to the constructor:

```
$numerals = function (): Generator {
    for ($i = 0; $i < 10; $i++) {
        yield $i;
    }
};

$iter = new SavingIterator(
    $numerals,
    new ArrayAddingIterator()
);
```

How to run tests
----------------

[](#how-to-run-tests)

First, install [Docker](https://www.docker.com/). After that, run:

```
docker-compose build

docker-compose run --rm php bash
```

After you start the container, install dependencies and run tests:

```
composer install

vendor/bin/phpunit tests
```

How to contribute
-----------------

[](#how-to-contribute)

[Fork this repository](https://docs.github.com/en/get-started/quickstart/fork-a-repo), then create a folder for it and install [Composer](https://getcomposer.org/download/) if you do not have it.

Clone this repository:

```
git clone https://github.com/MaxGoryunov/saving-iterator

```

Then run:

```
composer install
```

This command will install all dependencies required for development. Make changes and [open a pull request](https://github.com/MaxGoryunov/saving-iterator/pulls). Your PR will be reviewed and accepted if it does not fail our build.

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance51

Moderate activity, may be stable

Popularity8

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity69

Established project with proven stability

 Bus Factor1

Top contributor holds 99.7% 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 ~136 days

Recently: every ~0 days

Total

12

Last Release

267d ago

Major Versions

0.3 → 196.x-dev2025-08-22

196.x-dev → 200.x-dev2025-08-22

194.x-dev → 204.x-dev2025-08-23

PHP version history (3 changes)0.1.1PHP &gt;=7.4

0.1.2PHP &gt;=8.0

196.x-devPHP &gt;=8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/3adbd7a897f8906d93d64bca7fd7cdc7ad09442bed977b1d8dedfcbe76c9c1ff?d=identicon)[Max Goryunov](/maintainers/Max%20Goryunov)

---

Top Contributors

[![MaxGoryunov](https://avatars.githubusercontent.com/u/40582951?v=4)](https://github.com/MaxGoryunov "MaxGoryunov (629 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (2 commits)")

---

Tags

oopoop-libraryoop-principlesphpphp-library

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Psalm

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/maxgoryunov-saving-iterator/health.svg)

```
[![Health](https://phpackages.com/badges/maxgoryunov-saving-iterator/health.svg)](https://phpackages.com/packages/maxgoryunov-saving-iterator)
```

###  Alternatives

[lstrojny/procrastinator

Do things as late as possible in a request. Don’t let your users wait

6332.6k1](/packages/lstrojny-procrastinator)

PHPackages © 2026

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