PHPackages                             fast-forward/defer - 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. fast-forward/defer

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

fast-forward/defer
==================

Fast Forward Deferred Callbacks utility classes

v1.0.0(4mo ago)03312MITPHPPHP ^8.3CI passing

Since Mar 26Pushed 4mo agoCompare

[ Source](https://github.com/php-fast-forward/defer)[ Packagist](https://packagist.org/packages/fast-forward/defer)[ Docs](https://github.com/php-fast-forward/defer)[ RSS](/packages/fast-forward-defer/feed)WikiDiscussions main Synced 4w ago

READMEChangelog (1)Dependencies (4)Versions (2)Used By (2)

FastForward Defer
=================

[](#fastforward-defer)

[![PHP Version](https://camo.githubusercontent.com/c9b19f1cbf8aefb8c278c8b5d392b64401164a08fced6ccbf376b32135d6714f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e332d3737374242343f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://www.php.net/releases/)[![Composer Package](https://camo.githubusercontent.com/1e3852be788381bbfc13fee7f6eb94afca6f683257843c8a7af68ba17c2fb904/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f6d706f7365722d666173742d2d666f727761726425324664656665722d4632384431412e7376673f6c6f676f3d636f6d706f736572266c6f676f436f6c6f723d7768697465)](https://packagist.org/packages/fast-forward/defer)[![Tests](https://camo.githubusercontent.com/ebb999aaf73b14074d62eabb2655a9add277bafeff9c174afb8ec6fc51278c0d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7068702d666173742d666f72776172642f64656665722f74657374732e796d6c3f6c6f676f3d676974687562616374696f6e73266c6f676f436f6c6f723d7768697465266c6162656c3d746573747326636f6c6f723d323243353545)](https://github.com/php-fast-forward/defer/actions/workflows/tests.yml)[![Coverage](https://camo.githubusercontent.com/783041b70aa9cfca2a0969ddc49e11178a3367b14165ef787853fdc3075f43b3/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f7665726167652d706870756e69742d3441444538303f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://php-fast-forward.github.io/defer/coverage/index.html)[![Docs](https://camo.githubusercontent.com/8151276be4e7d9789089a03b7c76b3357572de7c66501cdf84d94b7a959e9098/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6465706c6f796d656e74732f7068702d666173742d666f72776172642f64656665722f6769746875622d70616765733f6c6f676f3d72656164746865646f6373266c6f676f436f6c6f723d7768697465266c6162656c3d646f6373266c6162656c436f6c6f723d31453239334226636f6c6f723d333842444638267374796c653d666c6174)](https://php-fast-forward.github.io/defer/index.html)[![License](https://camo.githubusercontent.com/b6ddeb8d82aacc6a041cc73acbcf50789dde6b0bac8b07f1df32db9d5eb6c130/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f7068702d666173742d666f72776172642f64656665723f636f6c6f723d363437343842)](LICENSE)[![GitHub Sponsors](https://camo.githubusercontent.com/d61f432861a7c60e0a9620738dffd3b884bcf392c86e48a2cc87ea57a077e90a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73706f6e736f72732f7068702d666173742d666f72776172643f6c6f676f3d67697468756273706f6e736f7273266c6f676f436f6c6f723d776869746526636f6c6f723d454334383939)](https://github.com/sponsors/php-fast-forward)

A minimal utility that brings **defer-style execution** (similar to Go) to PHP using object scope and destructors. It allows you to register callbacks that will run **automatically at the end of a scope**, in **LIFO order (Last-In, First-Out)**.

---

Core Concept
------------

[](#core-concept)

A Defer instance represents a **scope-bound execution stack**.

- Register callbacks using $defer(...) or $defer-&gt;defer(...)
- Callbacks execute automatically when the object goes out of scope
- Execution is always **LIFO (stack behavior)**
- Execution is **guaranteed during exception unwinding**
- Errors inside callbacks are **captured and reported**, without interrupting the chain

---

Basic Usage
-----------

[](#basic-usage)

```
use FastForward\Defer\Defer;

function example(): void
{
    $defer = new Defer();

    $defer(function () {
        echo "First defer\n";
    });

    $defer(function () {
        echo "Second defer\n";
    });

    echo "Inside function\n";
}

example();
```

### Output

[](#output)

```
Inside function
Second defer
First defer

```

---

Using Arguments
---------------

[](#using-arguments)

Deferred callbacks receive exactly the arguments you pass.

```
function example(): void
{
    $defer = new Defer();

    $defer(function ($file) {
        echo "Deleting {$file}\n";
    }, 'temp.txt');

    echo "Working...\n";
}

example();
```

### Output

[](#output-1)

```
Working...
Deleting temp.txt

```

---

⚠️ Execution Order Matters
--------------------------

[](#️-execution-order-matters)

Deferred callbacks execute in **reverse order of registration**.

```
$defer(fn() => unlink($file));
$defer(fn() => fclose($handle));
```

Execution order:

```
fclose($handle)
unlink($file)
```

Always register in **reverse of the desired execution order**.

---

Exception Safety
----------------

[](#exception-safety)

Deferred callbacks always run, even if an exception occurs.

```
function process(): void
{
    $defer = new Defer();

    $defer(fn() => print "Cleanup\n");

    throw new Exception('Failure');
}

try {
    process();
} catch (Exception) {
    echo "Exception caught\n";
}
```

### Output

[](#output-2)

```
Cleanup
Exception caught

```

---

Nested Scopes
-------------

[](#nested-scopes)

Each Defer instance is isolated.

```
function outer(): void
{
    $defer = new Defer();

    $defer(fn() => print "Outer cleanup\n");

    inner();
}

function inner(): void
{
    $defer = new Defer();

    $defer(fn() => print "Inner cleanup\n");
}

outer();
```

### Output

[](#output-3)

```
Inner cleanup
Outer cleanup

```

---

Helper Functions
----------------

[](#helper-functions)

### defer()

[](#defer)

Creates a new Defer instance.

```
Inside function
Second defer
First defer0

```

---

### scope()

[](#scope)

Runs a block with an isolated defer scope.

```
use function FastForward\Defer\scope;

scope(function ($defer) {
    $defer(fn() => print "Cleanup\n");

    echo "Inside\n";
});
```

---

### using()

[](#using)

Structured resource management (acquire → use → cleanup).

```
Inside function
Second defer
First defer2

```

---

Error Handling
--------------

[](#error-handling)

Deferred callbacks **never break execution flow**.

- If a callback throws, execution continues
- Errors are forwarded to an ErrorReporter
- Default behavior uses error\_log()

---

### Custom Error Reporter

[](#custom-error-reporter)

```
Inside function
Second defer
First defer3

```

---

### Composite Reporter

[](#composite-reporter)

```
Inside function
Second defer
First defer4

```

---

PSR Integration
---------------

[](#psr-integration)

### PSR-3 Logger

[](#psr-3-logger)

```
use FastForward\Defer\ErrorReporter\PsrLoggerErrorReporter;

Defer::setErrorReporter(
    new PsrLoggerErrorReporter($logger)
);
```

---

### PSR-14 Event Dispatcher

[](#psr-14-event-dispatcher)

```
Inside function
Second defer
First defer6

```

This allows multiple listeners (logging, metrics, tracing, etc.).

---

HTTP Middleware (PSR-15)
------------------------

[](#http-middleware-psr-15)

You can bind a Defer instance to a request lifecycle.

```
Inside function
Second defer
First defer7

```

The middleware:

- creates a Defer per request
- injects it into request attributes
- ensures execution at the end of the request

---

### Accessing Defer in Handlers

[](#accessing-defer-in-handlers)

```
use FastForward\Defer\DeferInterface;

$defer = $request->getAttribute(DeferInterface::class);
$defer(fn() => cleanup());
```

---

Execution Model
---------------

[](#execution-model)

### Within a single scope

[](#within-a-single-scope)

- Last registered → runs first

### Across nested scopes

[](#across-nested-scopes)

- Inner scope resolves before outer

---

Design Principles
-----------------

[](#design-principles)

- **Deterministic cleanup**
- **Minimal API**
- **No manual flush**
- **Failure isolation**
- **Extensible reporting**

---

Notes
-----

[](#notes)

- Execution is triggered by \_\_destruct()
- Do not share instances across scopes
- Prefer short-lived instances
- Avoid long-lived/global usage

---

When to Use
-----------

[](#when-to-use)

- resource cleanup
- file handling
- locks
- temporary state
- exception-safe teardown

---

When NOT to Use
---------------

[](#when-not-to-use)

- long-lived lifecycle management
- orchestration logic
- cases requiring explicit execution timing

---

Summary
-------

[](#summary)

Defer provides a strict and predictable cleanup model:

- automatic execution at scope end
- LIFO ordering
- safe failure handling
- pluggable reporting
- PSR-friendly integrations

It is intentionally **small, deterministic, and constrained**.

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance77

Regular maintenance activity

Popularity12

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

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

135d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/bb658791d4db57e57ac164a268f94340ddff4d1ee0aad1358d4593847051a9fe?d=identicon)[coisa](/maintainers/coisa)

---

Top Contributors

[![coisa](https://avatars.githubusercontent.com/u/426835?v=4)](https://github.com/coisa "coisa (13 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (1 commits)")

---

Tags

deferdeferredphpphp-helperphp-librarypsr-15psr-3

### Embed Badge

![Health badge](/badges/fast-forward-defer/health.svg)

```
[![Health](https://phpackages.com/badges/fast-forward-defer/health.svg)](https://phpackages.com/packages/fast-forward-defer)
```

###  Alternatives

[mcp/sdk

Model Context Protocol SDK for Client and Server applications in PHP

1.6k2.2M128](/packages/mcp-sdk)[jaxon-php/jaxon-core

Jaxon is an open source PHP library for easily creating Ajax web applications

73151.3k35](/packages/jaxon-php-jaxon-core)[flarum/core

Delightfully simple forum software.

211.5M2.5k](/packages/flarum-core)[xima/xima-typo3-frontend-edit

Frontend Edit - This extension provides an edit button for editors within frontend content elements.

1615.6k](/packages/xima-xima-typo3-frontend-edit)[eliashaeussler/typo3-solver

Solver - Extends TYPO3's exception handling with AI generated solutions. Problems can also be solved from command line. Several OpenAI parameters are configurable and prompts and solution providers can be customized as desired.

302.1k](/packages/eliashaeussler-typo3-solver)

PHPackages © 2026

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