Reading — step 1 of 5
Learn
~1 min readClosures and Iterators
PHP closures are objects of class Closure. Unlike most languages, PHP requires you to explicitly capture outer variables with use.
<?php
$base = 10;
$add = function ($n) use ($base) {
return $n + $base;
};
echo $add(5); // 15
$base = 20; // closure already captured 10
echo $add(5); // still 15
Capture by reference with &:
$counter = 0;
$inc = function () use (&$counter) {
$counter++;
};
$inc(); $inc(); $inc();
echo $counter; // 3
Arrow functions (PHP 7.4+) auto-capture (by value):
$base = 10;
$add = fn($n) => $n + $base; // implicitly use($base)
echo $add(5); // 15
Much shorter for simple cases. Cannot use use with fn.
Closure::bind — change $this for a closure:
class Counter {
private int $count = 0;
}
$reader = Closure::bind(
fn() => $this->count,
new Counter(),
Counter::class
);
echo $reader(); // 0 — even though count is private
This lets you peek at private state for debugging or testing.
Closure::fromCallable — convert any callable (string method names, arrays, ...) to a Closure:
class Math {
public static function add($a, $b) { return $a + $b; }
}
$add = Closure::fromCallable([Math::class, 'add']);
$add = Closure::fromCallable('Math::add'); // also works
echo $add(3, 4); // 7
First-class callable syntax (PHP 8.1+) — even cleaner:
$add = Math::add(...); // creates a Closure
$strlen = strlen(...);
$length = $strlen('hello'); // 5
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…