PHPackages                             vincenzoraco/again - 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. vincenzoraco/again

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

vincenzoraco/again
==================

A PHP package to follow best practices when using loops

v0.0.1(1y ago)31MITPHPPHP &gt;=8.2

Since Nov 19Pushed 1y ago1 watchersCompare

[ Source](https://github.com/vincenzoraco/again)[ Packagist](https://packagist.org/packages/vincenzoraco/again)[ RSS](/packages/vincenzoraco-again/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (5)Versions (2)Used By (0)

Again
=====

[](#again)

A handy utility package that lets you write loops in a declarative way and avoid infinite loops.

Installing
----------

[](#installing)

```
composer require vincenzoraco/again
```

Usage
-----

[](#usage)

When you need to execute a block of code repeatedly until a specific condition is met, you might typically use a `while`loop. For example:

```
while (!$this->isSent()) {
    $this->sendEmail();
}
```

This approach works, but it can lead to an **infinite loop** if the condition is never met or the exit condition is not properly defined. To prevent this, it is essential to add safeguards, such as limiting the number of iterations.

### Introducing Again

[](#introducing-again)

**Again** simplifies repetitive task execution with built-in safeguards to prevent infinite loops. It allows you to specify both a maximum number of iterations and a stopping condition, ensuring your loop behaves as expected.

Here’s how **Again** can help:

```
Again::perform(fn(int $i) => $this->sendEmail())
  ->limitTo(3)  // Stop after 3 attempts
  ->until(fn(int $i) => !$this->isSent())  // Stop if email is sent
  ->execute();
```

In this example, the email sending will attempt up to **3 times** until `$this->isSent()` is `true`. If the condition isn't met after 3 attempts, the loop will automatically stop, preventing an endless loop.

### Example with Custom Logic

[](#example-with-custom-logic)

You can also define your loop behavior using more complex logic by passing custom conditions or limits. For example:

```
$action = Again::perform($actionLogic)
  ->limitTo($limit)  // Limit the number of iterations
  ->until($until)  // Define the condition to stop
  ->execute();
```

### Know Why the Loop Ended

[](#know-why-the-loop-ended)

Sometimes you need to know why the loop has ended, whether it reached the maximum number of iterations or the stop condition was met. **Again** provides the `AgainStopReason` enum to indicate the reason for the loop termination.

For example:

```
$stopReason = Again::perform($actionLogic)
  ->limitTo($limit)
  ->until($until)
  ->execute();  // Execute and get the stop reason

// Check the reason for stopping
if ($stopReason === AgainStopReason::MAX_ITERATIONS_REACHED) {
    $this->notifyToSlack('Maximum retries reached.');
    // Handle the case when max iterations are reached
}

if ($stopReason === AgainStopReason::CONDITION_MET) {
    // Handle the case when the condition was met and the loop stopped
}
```

### Key Features:

[](#key-features)

- **Limit the number of iterations:** Use the `limitTo()` method to specify a maximum number of executions, preventing infinite loops.
- **Custom stop condition:** Use the `until()` method to define the condition that will cause the loop to stop when it evaluates to `true`.
- **Flexible execution:** Pass custom logic or actions to be executed on each iteration.
- **Track loop termination reason:** The `execute()` method returns an `AgainStopReason` value, letting you know why the loop ended.

Contributing
------------

[](#contributing)

You can contribute in one of three ways:

1. File bug reports using the [issue tracker](https://github.com/vincenzoraco/again/issues).
2. Answer questions or fix bugs on the [issue tracker](https://github.com/vincenzoraco/again/issues).
3. Contribute new features or update the wiki.

*The code contribution process is not very formal. You just need to make sure that you follow the PSR-0, PSR-1, and PSR-2 coding guidelines. Any new code contributions must be accompanied by unit tests where applicable.*

License
-------

[](#license)

MIT

###  Health Score

24

—

LowBetter than 32% of packages

Maintenance38

Infrequent updates — may be unmaintained

Popularity5

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 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.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

546d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3c687c2983ce5409447d3fc2d5129e34103a8dd9b16db7438d23fbace0412f4e?d=identicon)[vincenzoraco](/maintainers/vincenzoraco)

---

Top Contributors

[![vincenzoraco](https://avatars.githubusercontent.com/u/5623078?v=4)](https://github.com/vincenzoraco "vincenzoraco (1 commits)")

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/vincenzoraco-again/health.svg)

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

###  Alternatives

[dholmes/bga-workbench

BoardGameArena Workbench

375.3k](/packages/dholmes-bga-workbench)[limingxinleo/x-phalcon-enum

a phalcon enum component

104.4k1](/packages/limingxinleo-x-phalcon-enum)

PHPackages © 2026

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