Arrow Functions and Auto-Capture
fn() => ... is a one-expression closure that captures outer variables automatically, by value. Perfect for array_map and friends.
Arrow functions are closures with the ceremony removed. Two differences from function() {}: the body is a single expression whose value is returned automatically, and there's no use list — variables from the enclosing scope are captured by value automatically.
Easy example
<?php
$tax = 0.2;
$withTax = fn(float $price) => $price * (1 + $tax); // $tax auto-captured
echo $withTax(100); // 120Because they're so compact, arrow functions shine as callbacks. When you need multiple statements or a by-reference capture, fall back to a full closure.
Example
When to use it
- Pipe array_map over a list of order totals with an arrow function that captures a discount rate from the outer scope automatically.
- Use an arrow function as the array_filter callback to keep only products above a $minPrice threshold.
- Replace a verbose use()-closure in a one-liner array operation with an arrow function for cleaner code.
More examples
Auto-capture vs explicit use
Arrow functions capture outer variables by value automatically; no use() clause is needed.
<?php
$vat = 1.2;
// Regular closure needs explicit use()
$withVat1 = function (float $p) use ($vat): float { return $p * $vat; };
// Arrow function captures automatically
$withVat2 = fn(float $p): float => $p * $vat;
$prices = [10, 25, 50];
echo implode(', ', array_map($withVat2, $prices)); // 12, 30, 60Arrow function in array_filter
$minPrice is captured automatically from the outer scope; array_values() re-indexes the filtered result.
<?php
$minPrice = 10.0;
$products = [
['name' => 'Pen', 'price' => 1.99],
['name' => 'Bag', 'price' => 29.99],
['name' => 'Notebook', 'price' => 8.49],
['name' => 'Laptop', 'price' => 999.0],
];
$filtered = array_values(
array_filter($products, fn($p) => $p['price'] >= $minPrice)
);
foreach ($filtered as $p) {
echo "{$p['name']}: {$p['price']}\n";
}Chained higher-order functions
Arrow functions make chained array_map / array_filter pipelines concise without the noise of multiple use() clauses.
<?php
$discount = 0.1;
$prices = [100, 200, 300];
$discounted = array_map(fn($p) => $p * (1 - $discount), $prices);
$expensive = array_filter($discounted, fn($p) => $p > 150);
$total = array_sum($expensive);
echo $total; // 270
Discussion