PHPackages                             tito10047/php-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. tito10047/php-defer

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

tito10047/php-defer
===================

A defer function defers the execution of a function until the surrounding function returns.

2.0.2(1y ago)121731Apache-2.0PHPPHP &gt;=8.1CI passing

Since Mar 7Pushed 8mo ago1 watchersCompare

[ Source](https://github.com/tito10047/php-defer)[ Packagist](https://packagist.org/packages/tito10047/php-defer)[ RSS](/packages/tito10047-php-defer/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (1)Versions (6)Used By (0)

[![Tests](https://github.com/tito10047/php-defer/actions/workflows/unit-test.yml/badge.svg)](https://github.com/tito10047/php-defer/actions/workflows/unit-test.yml/badge.svg)[![Coverage Status](https://camo.githubusercontent.com/933d566c252892e5967bb74b87dc33ea1f73892cefd36d91b111eb0a8ddda094/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f7469746f31303034372f7068702d64656665722f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/tito10047/php-defer?branch=master)

In short
--------

[](#in-short)

Defer lets you schedule a cleanup action to run at the end of the current function/block. Use it right after acquiring a resource so you never forget to release it, even if you return early or an exception is thrown. Typical use cases include closing files, unlocking mutexes, or rolling back transactions.

Example:

```
function writeSomething(string $filename): void {
    $fh = fopen($filename, 'a');
    if ($fh === false) {
        throw new RuntimeException('Cannot open file');
    }
    $defer = defer(fclose(...), $fh); // will run when the function returns

    fwrite($fh, "hello\n");

    if (rand(0, 1)) {
        return; // fclose($fh) is still guaranteed to run
    }

    // more work...

    return; // fclose($fh) is still guaranteed to run
}
```

php-defer
=========

[](#php-defer)

### A php implementation of [defer](https://golang.org/doc/effective_go.html#defer) statement from [Go](https://golang.org/)

[](#a-php-implementation-of-defer-statement-from-go)

PHP defer function schedules a function call (the deferred function) to be run immediately before the function executing the defer returns. It's an unusual but effective way to deal with situations such as resources that must be released regardless of which path a function takes to return. The canonical examples are unlocking a mutex or closing a file.

```
// Contents returns the file's contents as a string.
function contents($filename) {
    $f = fopen($filename, "r");
    if ($f === false) {
        throw new Exception("Error opening the file");
    }
    $defer = defer(fclose(...),$f);  // fclose will run when we're finished.

    $result = "";

    while (($buffer = fread($f, 100)) !== false) {
        $result .= $buffer;
    }

    if (feof($f) === false) {
        // $f will be closed if we return here.
        throw new Exception("Error reading the file");
    }

    // $f will be closed if we return here.
    return $result;
}
```

Deferring a call to a function such as Close has two advantages. First, it guarantees that you will never forget to close the file, a mistake that's easy to make if you later edit the function to add a new return path. Second, it means that the close sits near the open, which is much clearer than placing it at the end of the function.

---

### Installation

[](#installation)

```
composer require tito10047/php-defer
```

Quick example
-------------

[](#quick-example)

```
function foo($a){
    echo "in defer {$a}".PHP_EOL;
}
function a() {
    echo "before defer".PHP_EOL;
    $defer = defer(foo(...),1);
    $defer(foo(...),2);
    $defer(foo(...),3);
    echo "after defer".PHP_EOL;
};

echo "start".PHP_EOL;
a();
echo "end".PHP_EOL;
```

will print

```
start
before defer
after defer
in defer 3
in defer 2
in defer 1
end

```

### 3 Rules

[](#3-rules)

---

The behavior of defer statements is straightforward and predictable. There are three simple rules:

`1.` *A deferred function's arguments are evaluated when the defer statement is evaluated.*

In this example, the expression "i" is evaluated when the printf call is deferred. The deferred call will print `0` after the function returns.

```
function a(){
    $i=0;
    $_ = defer(printf(...),$i);
    $i++;
}
```

will print `000`

`2.` *Deferred function calls are executed in Last In First Out order after the*surrounding function returns.

This function prints `3210`:

```
function b(){
    $defer = defer();
    for($i=0;$ii` *after* the surrounding function returns but not modify returned `$i`. This example print `2-3`:

```
function c() {
    $i=1;
    $o=new \stdClass();
    $o->i=2;
    $defer = defer(function () use (&$i, $o) {
        $o->i++;
        $i++;
    });

    $i++;
    return [$i,$o];
}
list($i,$o) = c();
echo "{$i}-{$o->i}".PHP_EOL;
```

---

### PHP Limitations

[](#php-limitations)

- In php defer implementation you can't modify returned value. Can modify only content of returned reference
- You need instantiate defer object before use it with `$defer = new Defer()` or `$defer = defer()`

---

### Usage

[](#usage)

```
namespace test;

require_once __DIR__.'/../vendor/autoload.php';

function myFunc(){}
class Foo{
    public function myMethod(){}
}
function a(){
    // defer custom function without parameter
    // function name must be with his namespace
    $defer = defer('test\myFunc');
    // defer function with one parameter
    $defer(printf(...),"test");
    // defer function with more parameters
    $defer('printf',"%s-%s",10,12);
    // defer with anonymous function
    $defer(function (){});
    $func = function (){};
    $defer($func);
    //defer method
    $foo = new Foo();
    $defer([$foo,'myMethod']);
}
a();
```

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance48

Moderate activity, may be stable

Popularity22

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity76

Established project with proven stability

 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

Every ~683 days

Total

5

Last Release

619d ago

Major Versions

1.0.0 → 2.0.02024-08-27

1.0.1 → 2.0.12024-08-27

### Community

Maintainers

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

---

Top Contributors

[![tito10047](https://avatars.githubusercontent.com/u/11459248?v=4)](https://github.com/tito10047 "tito10047 (30 commits)")

---

Tags

phpdefer

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/tito10047-php-defer/health.svg)

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

###  Alternatives

[imanghafoori/laravel-anypass

A minimal yet powerful package to help you in development.

21421.6k](/packages/imanghafoori-laravel-anypass)

PHPackages © 2026

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