Skip to content
Closures and use Clause
step 1/6

Reading — step 1 of 6

Learn

~2 min readFunctional Patterns

PHP closures are first-class values — assignable, passable, returnable. But they capture variables differently from JavaScript or Python.

Anonymous functions

$double = function(int $n): int {
    return $n * 2;
};

echo $double(5);    // 10

A Closure is an instance of the built-in \Closure class.

The use clause — capturing

Unlike JS and Python, PHP closures DON'T capture parent variables automatically. You must list them with use:

$factor = 3;

$multiply = function(int $n) use ($factor): int {
    return $n * $factor;
};

echo $multiply(7);    // 21

Capture is by value by default — it's a snapshot at definition time:

$x = 10;
$f = function() use ($x) { return $x; };
$x = 99;
echo $f();             // 10 — captured the original

For by-reference, prefix with &:

$x = 10;
$f = function() use (&$x) { return $x; };
$x = 99;
echo $f();             // 99 — sees the live $x

Arrow functions (PHP 7.4+)

Shorter syntax, AUTOMATIC capture by value of all needed outer variables:

$factor = 3;
$multiply = fn(int $n) => $n * $factor;    // no `use` clause needed

echo $multiply(7);    // 21

Limitations:

  • Single expression only (no statements)
  • No way to capture by reference
  • Always returns the expression's value

Great for short callbacks: array_map(fn($x) => $x * 2, $nums).

Closures with array_* functions

The sweet spot for closures:

$evens = array_filter([1,2,3,4,5], fn($n) => $n % 2 === 0);   // [2, 4]
$doubled = array_map(fn($n) => $n * 2, [1,2,3]);              // [2, 4, 6]
$total = array_reduce([1,2,3,4], fn($carry, $n) => $carry + $n, 0);  // 10

bindTo and binding $this

Closures can be bound to an object so $this works inside:

class User {
    public string $name = 'Ada';
}

$greet = function() { return "Hi, $this->name"; };
$bound = Closure::bind($greet, new User(), User::class);
echo $bound();    // Hi, Ada

Useful for adding methods to objects after the fact — frameworks lean on this.

Common mistakes

  • Forgetting use — variables from the parent scope are NOT auto-captured in regular closures. function() { return $x; } won't see outer $x.
  • Capturing by value when you wanted by referenceuse ($x) snapshots; subsequent changes to outer $x are invisible inside.
  • Assuming arrow functions can have a body — they're expression-only.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…