Closures and Variable Binding with use()
PHP closures explicitly capture variables from the enclosing scope with use(). This isn't a limitation — it's a feature. You always know exactly what a closure depends on, making the code easier to reason about and debug.
// Explicit capture — no hidden dependencies
$multiplier = 1.21; // VAT rate
$applyVat = function (float $price) use ($multiplier): float {
return $price * $multiplier;
};
// Capture by reference for stateful closures
function createCounter(int $start = 0): Closure {
$count = $start;
return function () use (&$count): int {
return $count++;
};
}
$counter = createCounter();
echo $counter(); // 0
echo $counter(); // 1
// Closures can bind to objects — powerful for DSLs
$closure = Closure::bind(function () {
return $this->secret; // Access private property
}, $object, get_class($object));
// Middleware pattern with closures
$middleware = function (Request $request, Closure $next): Response {
// Before
$response = $next($request);
// After
return $response;
};
The explicit use() clause means you can look at any closure and immediately see its external dependencies. Combined with Closure::bind() and Closure::fromCallable(), PHP closures are flexible enough for any functional or object-oriented pattern.
Significance: Explicitness
Implicit variable capture (like JavaScript's) can lead to subtle bugs and memory leaks. PHP's explicit
use() clause makes the closure's contract visible: you see exactly what it captures, whether by value or reference. Explicit is better than implicit.