PHP Arrow Functions
last modified May 21, 2025
This tutorial dives into PHP arrow functions, also known as short closures, introduced in PHP 7.4 to simplify function syntax.
Arrow functions provide a concise and readable way to define anonymous
functions, eliminating the need for explicit use
statements
when capturing variables from the parent scope. They enhance code clarity
and improve maintainability, making them ideal for simple callbacks, array
manipulations, and inline operations.
Arrow functions are particularly useful in functional programming
paradigms, where functions are treated as first-class citizens. They
allow for cleaner and more expressive code, especially when used with
array functions like array_map
, array_filter
, and
usort
.
The following table summarizes the key differences between arrow functions and regular closures in PHP.
Feature | Arrow Functions | Regular Closures |
---|---|---|
Variable Capture | Automatically captures variables by value. | Requires explicit use to capture external variables. |
Return Behavior | Implicit return (evaluates and returns the expression). | Requires explicit return statement. |
Multi-Statement Support | Not supported; only single expressions. | Fully supports multi-statement blocks inside {}. |
Modification of Captured Variables | Cannot modify captured variables. | Allows modification when passed by reference (use (&$var)). |
$this Binding |
Preserves $this from the declaring scope. |
$this can be rebound using bindTo . |
Scope Control | Uses static lexical scope; cannot be rebound. | Allows dynamic scope rebinding. |
This table summarizes the key differences between arrow functions and regular closures in PHP. Arrow functions are designed for simplicity and conciseness, making them ideal for straightforward use cases. Regular closures offer more flexibility and control, especially for complex logic and multi-statement functions.
Basic arrow function syntax
Arrow functions use the fn keyword instead of function and have a simplified syntax. They automatically inherit variables from the parent scope without needing the use keyword. The return is implicit for single expressions.
<?php declare(strict_types=1); // Traditional closure $addOld = function($a, $b) { return $a + $b; }; // Arrow function equivalent $addNew = fn($a, $b) => $a + $b; echo $addOld(5, 3) . "\n"; // 8 echo $addNew(5, 3) . "\n"; // 8 // Automatic variable capture $factor = 10; $multiplier = fn($x) => $x * $factor; echo $multiplier(5) . "\n"; // 50 // Type declarations (PHP 8.0+) $concat = fn(string $a, string $b): string => $a . $b; echo $concat("Hello ", "there!") . "\n";
This shows the basic syntax of arrow functions compared to traditional closures. Arrow functions automatically capture $factor from the parent scope. PHP 8.1 added support for multi-statement arrow functions with explicit returns.
λ php basic_arrow.php 8 8 50 Hello there!
Variable inheritance
Arrow functions automatically inherit variables from the parent scope by value (not by reference). This differs from traditional closures which require explicit use statements to capture variables.
<?php declare(strict_types=1); $prefix = "User_"; $id = 100; // Traditional closure with use $oldFormat = function() use ($prefix, $id) { return $prefix . $id; }; // Arrow function automatically captures $newFormat = fn() => $prefix . $id; echo $oldFormat() . "\n"; // User_100 echo $newFormat() . "\n"; // User_100 // Variables are captured by value $id = 200; echo $oldFormat() . "\n"; // Still User_100 echo $newFormat() . "\n"; // Still User_100 // Objects are captured by reference $user = new class { public string $name = 'John'; }; $getName = fn() => $user->name; $user->name = 'Alice'; echo $getName() . "\n"; // Alice (reference) // Cannot modify captured variables $counter = 0; $increment = fn() => $counter++; // Cannot modify counter echo $increment() . "\n";
This demonstrates how arrow functions inherit variables. Scalar values are captured by value at function creation, while objects are captured by reference. Unlike regular closures, arrow functions cannot modify inherited variables.
λ php variable_inheritance.php User_100 User_100 User_100 User_100 Alice 0
Common use cases
Arrow functions are particularly useful for array operations, callbacks, and simple transformations where their concise syntax improves readability.
<?php declare(strict_types=1); // Array operations $numbers = [1, 2, 3, 4, 5]; $squared = array_map(fn($n) => $n ** 2, $numbers); print_r($squared); // Filtering $even = array_filter($numbers, fn($n) => $n % 2 === 0); print_r($even); // Sorting $users = [ ['name' => 'Alice', 'age' => 25], ['name' => 'Bob', 'age' => 30], ['name' => 'Charlie', 'age' => 20] ]; usort($users, fn($a, $b) => $a['age'] <=> $b['age']); print_r($users); // Callbacks $greet = function(string $name, callable $formatter) { echo $formatter($name) . "\n"; }; $greet('John', fn($n) => "Hello, $n!"); // Object method callbacks class Calculator { public function calculate(array $values, callable $operation): array { return array_map($operation, $values); } } $calc = new Calculator(); $result = $calc->calculate([1, 2, 3], fn($x) => $x * 10); print_r($result); // Immediately invoked function expression (IIFE) $result = (fn($x, $y) => $x + $y)(5, 3); echo "IIFE result: $result\n";
These examples show typical scenarios where arrow functions shine. They're
especially useful with array functions like array_map
and
array_filter
. The concise syntax makes callback-heavy code more
readable.
Advanced usage patterns
Arrow functions can be used in more advanced patterns like currying, function composition, and as method return values. These patterns benefit from their concise syntax.
<?php declare(strict_types=1); // 1. Currying with Arrow Functions function multiply(float $a): callable { return fn(float $b) => $a * $b; } $double = multiply(2); $triple = multiply(3); echo "Double: " . $double(5) . "\n"; // 10 echo "Triple: " . $triple(5) . "\n"; // 15 // 2. Function Composition function compose(callable ...$functions): callable { return fn($x) => array_reduce( array_reverse($functions), fn($carry, $f) => $f($carry), $x ); } $addOne = fn($x) => $x + 1; $square = fn($x) => $x * $x; $addThenSquare = compose($square, $addOne); echo "Composed function result: " . $addThenSquare(3) . "\n"; // (3 + 1)^2 = 16 // 3. Factory Pattern with Arrow Functions class OperationFactory { public static function create(string $type): callable { return match($type) { 'add' => fn($a, $b) => $a + $b, 'sub' => fn($a, $b) => $a - $b, 'mul' => fn($a, $b) => $a * $b, 'div' => fn($a, $b) => $b != 0 ? $a / $b : throw new InvalidArgumentException("Cannot divide by zero"), default => throw new InvalidArgumentException("Unknown operation"), }; } } $adder = OperationFactory::create('add'); echo "Factory pattern (Addition): " . $adder(10, 5) . "\n"; // 15 // 4. Logging with Arrow Functions function createLogger(string $prefix): callable { return fn(string $message) => "[$prefix] $message\n"; } $errorLogger = createLogger('ERROR'); $infoLogger = createLogger('INFO'); echo $errorLogger('Something went wrong'); echo $infoLogger('Process completed'); // 5. Recursive Arrow Functions (PHP 8.1+) $factorial = function(int $n) use (&$factorial): int { return $n <= 1 ? 1 : $n * $factorial($n - 1); }; echo "Factorial of 5: " . $factorial(5) . "\n"; // 120
These advanced patterns demonstrate the power of arrow functions in functional programming styles. The concise syntax makes function composition and higher-order functions more readable. Note that recursive arrow functions require PHP 8.1+ and a reference to themselves.
λ php advanced_patterns.php Double: 10 Triple: 15 Composed function result: 16 Factory pattern (Addition): 15 [ERROR] Something went wrong [INFO] Process completed Factorial of 5: 120
PHP arrow functions provide a concise syntax for writing closures with automatic variable capture from the parent scope. Key points to remember:
- Introduced in PHP 7.4 with
fn
keyword and=>
syntax. - Automatically captures variables by value from the parent scope.
- Implicit return for single-expression functions.
- Cannot modify captured variables or use by-reference parameters.
- Maintains original
$this
binding within class contexts. - Best suited for simple callbacks and array operations due to concise syntax.
- Has more limitations compared to traditional closures.
- Improved in PHP 8.1 with multi-statement support for increased flexibility.
In this article, we explored the syntax and usage of PHP arrow functions. We covered their differences from traditional closures, common use cases, and advanced patterns.
Author
List all PHP tutorials.