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(3mo ago)03312MITPHPPHP ^8.3CI passing

Since Mar 26Pushed 2mo 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 3w 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

41

—

FairBetter than 87% of packages

Maintenance84

Actively maintained with recent releases

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

90d 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.5k937.5k68](/packages/mcp-sdk)[psr7-sessions/storageless

Storageless PSR-7 Session support

650396.3k8](/packages/psr7-sessions-storageless)[fisharebest/webtrees

webtrees online genealogy

77416.0k20](/packages/fisharebest-webtrees)[jaxon-php/jaxon-core

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

73147.2k29](/packages/jaxon-php-jaxon-core)[flarum/core

Delightfully simple forum software.

201.4M2.2k](/packages/flarum-core)[dtm/dtm-client

A PHP coroutine client for distributed transaction manager DTM. 分布式事务管理器 DTM 的 PHP 协程客户端

34735.1k6](/packages/dtm-dtm-client)

PHPackages © 2026

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